Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic way to store preferences in .bib file / self-contained library settings #8701

Open
ColinScarato opened this issue Apr 20, 2022 · 17 comments

Comments

@ColinScarato
Copy link

Jabref allows to store part of its settings in a database-specific way directly in a given .bib file: https://docs.jabref.org/setup/databaseproperties

I would find super useful to be able to store more of these settings in a .bib file (use case: a big group of collaborators working on a database under version control, with a lot of settings that we currently need to maintain for every collaborator separately). Given that there is already a mechanism to export/import these preferences with an .xml file, could it be possible to implement this in a similar way for .bib files, in order to automatically load all of these preferences if present when opening a given database? Or does Jabref only support globally setting some of these values?

In particular I would need the following settings:

  • mainTableColumnNames
  • mainTableColumnSortTypes
  • mainTableColumnSortOrder
  • customTabName_0
  • customTabFields_0
  • useOwner
  • addCreationDate
  • reformatFileOnSaveAndExport
  • useRemoteServer
  • bibLocAsPrimaryDir
  • customizedBibtexTypes

Thanks!

@yanyanliu1400
Copy link
Contributor

Hi, I am a new contributor to and I would like to make an attempt at resolving this issue. Could it please be assigned to me?

I have followed the instructions and set up a local workspace.

I have also read the contribution guide.

I was hoping I could receive some advice/pointers on where to begin with this issue.

@ThiloteE
Copy link
Member

Marking this with devcall to explore the idea of storing more preferences in the bib file.

Related issue: #8836

What speaks for this:

  • Eases maintaining of shared databases

What speaks against:

  • Bib file pollution (When it is NOT wanted to automatically load preferences from colleagues in a shared database)
  • Most (but not all) JabRef preferences are stored elsewhere (might lead to confusion)

@yanyanliu1400 this is a tough issue that requires a lot of thinking so as to not create problems for many people that are not in need of these specific preferences. Since this is your first contribution to JabRef, please have a look at our projects page with "good first issues". If you are a student, the "candidates for university projects" page offers some issues of varying difficulty and scope and that have been estimated to be compatible with university courses as well and often bring a larger feature to JabRef. I think you already found another issue to work on though.

@koppor
Copy link
Member

koppor commented Oct 24, 2022

Workaround

Alternatively, one could export the JabRef preferences and have all users importing the database.

Local Library Settings (Solution with one file)

  • useOwner
    grafik
  • addCreationDate
    grafik
  • reformatFileOnSaveAndExport
  • useRemoteServer --> This is already possible when a bib file is synchronized with a local file - https://docs.jabref.org/collaborative-work/sqldatabase. Maybe, it does not work as expected when the bib file is opened by a user not having connected to the database yet
    grafik
  • bibLocAsPrimaryDir --> This is not required because one can set "." as main file directory
    grafik
  • customizedBibtexTypes - Documentation: https://docs.jabref.org/setup/customentrytypes - currently, JabRef stores the used entry types
  • Linked File Name
    • grafik
    • grafik
  • mainTableColumnNames
  • mainTableColumnSortTypes
  • mainTableColumnSortOrder
  • customTabName_0
  • customTabFields_0

UI: Each check tri-state: selected, unslected, grayed-out. If grayed-out, the global setting is used and the grayed-out box should be in the state of the global configuration.

Note: This approach is simlar to the file directory setting approach of JabRef:

grafik

Solution with multiple files (workspace concept)

JabRef could introduce the concept of a workspace, where multiple files are included. When sharing, the complete folder could be shared. The folder could contain

Similar to IntelliJ's global preferences and module-/project-specific preferences.

(not chosen) Solution with exported preferences handled by JabRef

Filename is papers.bib. There could be a file papers.jabref-preferences.xml. If JabRef finds that file, it loads these preferences when the library is focused. If it is unfocused, then the "old" preferences are restored.

Alternative: In the meta data, the path to the preferences can be configured.

  1. grafik --> preferences of "test541.bib" are loaded
  2. grafik --> global preferences are used
  • Bad, because performance could go low (because of the abbreviations)
  • Bad, because possibly non-understandable by users

@koppor
Copy link
Member

koppor commented Oct 24, 2022

If tackling this issue, each setting has to be investigated separately:

  • Locate the settings component in our property dialog code and make that component resuable (see the Key Patterns component as example)
    grafik
    grafik
  • Include the setting in the library properties
  • Have the preference resolution ask the library setting and then the global setting
  • Adapt initialization of setting

@taliashark77
Copy link

Hi I'm a university student with an assignment to contribute to an open source repository, would this be a good issue for me to work on?

@ThiloteE
Copy link
Member

@taliashark77 at the right top side of github you see the projects page. While this is marked as good first issue, I assume it was more because this project can be seen as a good first entry into our code base.

This is a medium sized project, as you can see here:
image

Since this would be your first ever pull-request on GitHub, I assume you are very new to coding and therefore, I suggest to check out our good first issues projects page or alternatively choose one of the small projects. I recommend this issue to students with a little bit more experience. E.g. non-first semesters or somebody who has started to code before joining university.

@taliashark77
Copy link

@ThiloteE Thanks for your response, I will try look for some more beginner friendly issues

@koppor koppor removed the good first issue An issue intended for project-newcomers. Varies in difficulty. label Oct 23, 2023
@mwinter80
Copy link

Hi All. I have posted a similar request here:

https://discourse.jabref.org/t/different-entry-table-views/4125/3

For now, I have done something completely insane. Which is to created a separate preferences file for each bib file and then created a launcher for each that loads the respective bib file along with the corresponding preferences with the appropriate arguments.

Just a thought of the top of my head... Perhaps something simpler could be done regarding the order of how the preferences are checked. That is maybe before checking the system configs seeing if there is a preferences file that matches the name of the bib file in a specified folder. So, if it does not exist, jabref is launched with the preferences that are stared at the java level (or wherever it is on the system). If there is a file match, then those preference are loaded.

@koppor
Copy link
Member

koppor commented Jan 9, 2024

seeing if there is a preferences file that matches the name of the bib file in a specified folder.

Maybe, that file could even be stored along side the .bib file? Then it would also be sharable using git or OneDrive.

@mwinter80
Copy link

seeing if there is a preferences file that matches the name of the bib file in a specified folder.

Maybe, that file could even be stored along side the .bib file? Then it would also be sharable using git or OneDrive.

seems reasonable and simple : )

@koppor
Copy link
Member

koppor commented Jan 11, 2024

Code hint for the "straight-forward" along-side storage:

  • org.jabref.preferences.JabRefPreferences#flush

This comment will updated with other code hints as soon as I stumple on them.

@mwinter80
Copy link

It has been a while since I have been in Java-land, but I could help here. I looked at the code around line 497 would be where the check happens as there is already one there. The tricker part will be how to deal with the hook such that there is a check based on the bib file that is being opened.

@koppor
Copy link
Member

koppor commented Jan 11, 2024

Fortunately, we have a step-by-step-guide to setup a local workspace: https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/#setup-for-eclipse 🤣🤣

General thoughts:

  • JabRef can have multiple opened libraries. One library can have library-specific preferences, one not.
  • We do not want to rewrite the whole preference logic, the "hack" with the portable preferences seems to have less code
  • We want to have the "magic" being enabled only if there is one library opened with library-specific preferences.

Consequences:

  • Thus, we need global-profs.xml. Can be stored in AppData\Local\org.jabref\jabref\settings. New method analogues to org.jabref.gui.desktop.os.NativeDesktop#getBackupDirectory needed.
  • Global flag libararySpecificSettingsInPlace. Default: false. Held in org.jabref.gui.StateManager
  • On focus a library hook into
    • org.jabref.gui.LibraryTab#LibraryTab --> add setOnSelectionChanged
  • hook:
    • on focus lost: store old preferences (if available)
    • on focus gained: load new preferences
  • hook into closed library (maybe not necessary, because of other hook, I am not sure about the live cycle)
    • store old preferences
  • store old preferences: only required if local settings are available
  • load new preferences: only if local settings are available
  • in bibdatabasecontext.getmetadata, it should be stored if local should be used. (boolean)

(Have to leave now, with the metadata, i am not sure how to full. Maybe quick hack: return files.exists(...xml) so that the property is magically filled)

@mwinter80
Copy link

Ok! Very insightful. It might take me a bit to get up and running. I will keep you posted...

@koppor
Copy link
Member

koppor commented Jan 12, 2024

Just a note for a technical motivation for the issue - not related to the currently proposed first-solution. This is more a comment for the long run.

    @BeforeEach
    public void setUp() {
        importer = new BibtexImporter(mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS), new DummyFileUpdateMonitor());

        stringWriter = new StringWriter();
        bibWriter = new BibWriter(stringWriter, OS.NEWLINE);
        saveConfiguration = new SelfContainedSaveConfiguration(SaveOrder.getDefaultSaveOrder(), false, BibDatabaseWriter.SaveType.WITH_JABREF_META_DATA, false);
        fieldPreferences = new FieldPreferences(true, Collections.emptyList(), Collections.emptyList());
        citationKeyPatternPreferences = mock(CitationKeyPatternPreferences.class, Answers.RETURNS_DEEP_STUBS);
        entryTypesManager = new BibEntryTypesManager();

        databaseWriter = new BibtexDatabaseWriter(
                bibWriter,
                saveConfiguration,
                fieldPreferences,
                citationKeyPatternPreferences,
                entryTypesManager);
    }

    @Test
    void anonymizeLibrary() throws Exception {
        Path path = Path.of("C:\\temp\\P4\\biblio.bib");
        BibDatabaseContext databaseContext = importer.importDatabase(path).getDatabaseContext();

        Anonymization anonymization = new Anonymization();
        BibDatabaseContext result = anonymization.anonymizeLibrary(databaseContext);

        databaseWriter.saveDatabase(databaseContext);

        Files.writeString(Path.of("C:\\temp\\P4\\biblio-anon.bib"), stringWriter.toString());

        assertEquals(null, result);
    }

In the long run, a simple read and write of a library should use defaults - and not require some library-external preferences.

@koppor
Copy link
Member

koppor commented Mar 3, 2024

First step: Support keywords per library:

image

Then, one learns about the consequences and can cover the other preferences step-by-step. With "learn", I mean: the right architecture, the necessary code changes, ... Maybe, we even need a generic preferencesFactory being initialized with the BibDatabaseContext and the JabRefPreferenceService - and then first checks the context. If not set, then it checks the global preferences. I think, this is the most stramlined way.

Especially, following code in GrammarBasedSearchRule needs to be updated

            if (fieldPattern.matcher("anykeyword").matches()) {
                return entry.getKeywords(',').stream().map(Keyword::toString).anyMatch(this::matchFieldValue);
            }

@koppor koppor changed the title Generic way to store preferences in .bib file Generic way to store preferences in .bib file / self-contained library settings Sep 13, 2024
@koppor
Copy link
Member

koppor commented Sep 13, 2024

  • Add a dynamic notice in preferences: "You currently opened libraries: L1, L2, L3 - contain local setting of X, settings will not be applied to those libraries"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Free to take
Status: Normal priority
Development

No branches or pull requests

7 participants