jabref
jabref copied to clipboard
Generic way to store preferences in .bib file
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!
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.
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.
Workaround
Alternatively, one could export the JabRef preferences and have all users importing the database.
Local Library Settings (Solution with one file)
- useOwner
- addCreationDate
- 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
- bibLocAsPrimaryDir --> This is not required because one can set "." as main file directory
- customizedBibtexTypes - Documentation: https://docs.jabref.org/setup/customentrytypes - currently, JabRef stores the used entry types
- Linked File Name
-
- 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:
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
- Shared preferences
- Related references (see https://github.com/JabRef/jabref/pull/7160#issuecomment-757556724)
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.
-
--> preferences of "test541.bib" are loaded
-
--> global preferences are used
- Bad, because performance could go low (because of the abbreviations)
- Bad, because possibly non-understandable by users
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)
- Include the setting in the library properties
- Have the preference resolution ask the library setting and then the global setting
- Adapt initialization of setting
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?
@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:
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.
@ThiloteE Thanks for your response, I will try look for some more beginner friendly issues
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.
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.
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 : )
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.
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.
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 inAppData\Local\org.jabref\jabref\settings
. New method analogues toorg.jabref.gui.desktop.os.NativeDesktop#getBackupDirectory
needed. - Global flag
libararySpecificSettingsInPlace
. Default:false
. Held inorg.jabref.gui.StateManager
- On focus a library hook into
-
org.jabref.gui.LibraryTab#LibraryTab
--> addsetOnSelectionChanged
-
- 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)
Ok! Very insightful. It might take me a bit to get up and running. I will keep you posted...
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.
First step: Support keywords
per library:
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);
}