Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
### Added

- We added automatic date-based groups that create year/month/day subgroups from an entry’s date fields. [#10822](https://github.com/JabRef/jabref/issues/10822)
- We added support for transliteration of fields to English and automatic transliteration of generated citation key. [#11377](https://github.com/JabRef/jabref/issues/11377) [#9605](https://github.com/JabRef/jabref/issues/9605)

### Changed

Expand Down Expand Up @@ -51,6 +52,25 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We added chronological navigation for entries in each library. [#6352](https://github.com/JabRef/jabref/issues/6352)
- We added support for using Medline/Pubmed fetcher with an API key. [#11296](https://github.com/JabRef/jabref/issues/11296#issuecomment-3289005011)
- We added support for using OpenAlex fetcher. [#13940](https://github.com/JabRef/jabref/issues/13940)
- We added an option to choose the group during import of the entry(s). [#9191](https://github.com/JabRef/jabref/issues/9191)
- We added an option to search and filter the fields and formatters in the Clean up entries dialog. [#13890](https://github.com/JabRef/jabref/issues/13890)
- We added support for managing multiple linked files via the entry context menu. [#12567](https://github.com/JabRef/jabref/issues/12567)

### Changed

- We changed `ISSNCleanup` into `NormalizeIssn` a `ISSN` formatter. [#13748](https://github.com/JabRef/jabref/issues/13748)
- We changed Citation Relations tab and gave tab panes more descriptive titles and tooltips. [#13619](https://github.com/JabRef/jabref/issues/13619)
- We changed the name from Open AI Provider to Open AI (or API compatible). [#13585](https://github.com/JabRef/jabref/issues/13585)
- We improved the citations relations caching by implementing an offline storage. [#11189](https://github.com/JabRef/jabref/issues/11189)
- We added a tooltip to keywords that resemble Math Subject Classification (MSC) codes. [#12944](https://github.com/JabRef/jabref/issues/12944)
- We added a formatter to convert keywords that resemble MSC codes to their descriptions. [#12944](https://github.com/JabRef/jabref/issues/12944)
- We introduced a new command line application called `jabkit`. [#13012](https://github.com/JabRef/jabref/pull/13012) [#110](https://github.com/JabRef/jabref/issues/110)
- We added a new "Add JabRef suggested groups" option in the context menu of "All entries". [#12659](https://github.com/JabRef/jabref/issues/12659)
- We added an option to create entries directly from Bib(La)TeX sources to the 'Create New Entry' tool. [#8808](https://github.com/JabRef/jabref/issues/8808)
- We added the provision to choose different CSL bibliography body formats (e.g. First Line Indent, Hanging Indent, Bibliography 1, etc.) in the LibreOffice integration. [#13049](https://github.com/JabRef/jabref/issues/13049)
- We use `https` to connect to [shortDOI](https://shortdoi.org/) service. [#13637](https://github.com/JabRef/jabref/pull/13637)
- We added "Bibliography Heading" to the available CSL bibliography header formats in the LibreOffice integration. [#13049](https://github.com/JabRef/jabref/issues/13049)
- We added support for using OpenAlex fetcher. [#13940](https://github.com/JabRef/jabref/issues/13940)
- We added [LOBID](https://lobid.org/) as an alternative ISBN-Fetcher. [#13076](https://github.com/JabRef/jabref/issues/13076)
- We added an option to choose the group during import of the entry(s). [#9191](https://github.com/JabRef/jabref/issues/9191)
- We added an option to search and filter the fields and formatters in the clean up entries dialog. [#13890](https://github.com/JabRef/jabref/issues/13890)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

public class CitationKeyPatternTab extends AbstractPreferenceTabView<CitationKeyPatternTabViewModel> implements PreferencesTab {

@FXML private CheckBox transliterateFieldsForCitationKey;
@FXML private CheckBox overwriteAllow;
@FXML private CheckBox overwriteWarning;
@FXML private CheckBox generateOnSave;
Expand All @@ -42,6 +43,7 @@ public String getTabName() {
public void initialize() {
this.viewModel = new CitationKeyPatternTabViewModel(preferences.getCitationKeyPatternPreferences(), preferences.getImporterPreferences());

transliterateFieldsForCitationKey.selectedProperty().bindBidirectional(viewModel.transliterateFieldsForCitationKeyProperty());
overwriteAllow.selectedProperty().bindBidirectional(viewModel.overwriteAllowProperty());
overwriteWarning.selectedProperty().bindBidirectional(viewModel.overwriteWarningProperty());
generateOnSave.selectedProperty().bindBidirectional(viewModel.generateOnSaveProperty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

public class CitationKeyPatternTabViewModel implements PreferenceTabViewModel {

private final BooleanProperty transliterateFieldsForCitationKeyProperty = new SimpleBooleanProperty();
private final BooleanProperty overwriteAllowProperty = new SimpleBooleanProperty();
private final BooleanProperty overwriteWarningProperty = new SimpleBooleanProperty();
private final BooleanProperty generateOnSaveProperty = new SimpleBooleanProperty();
Expand Down Expand Up @@ -53,6 +54,7 @@ public CitationKeyPatternTabViewModel(CitationKeyPatternPreferences keyPatternPr

@Override
public void setValues() {
transliterateFieldsForCitationKeyProperty.setValue(keyPatternPreferences.shouldTransliterateFieldsForCitationKey());
overwriteAllowProperty.setValue(!keyPatternPreferences.shouldAvoidOverwriteCiteKey());
overwriteWarningProperty.setValue(keyPatternPreferences.shouldWarnBeforeOverwriteCiteKey());
generateOnSaveProperty.setValue(keyPatternPreferences.shouldGenerateCiteKeysBeforeSaving());
Expand Down Expand Up @@ -106,6 +108,7 @@ public void storeSettings() {
keySuffix = CitationKeyPatternPreferences.KeySuffix.SECOND_WITH_B;
}

keyPatternPreferences.setShouldTransliterateFieldsForCitationKey(transliterateFieldsForCitationKeyProperty.getValue());
keyPatternPreferences.setAvoidOverwriteCiteKey(!overwriteAllowProperty.getValue());
keyPatternPreferences.setWarnBeforeOverwriteCiteKey(overwriteWarningProperty.getValue());
keyPatternPreferences.setGenerateCiteKeysBeforeSaving(generateOnSaveProperty.getValue());
Expand All @@ -117,6 +120,10 @@ public void storeSettings() {
keyPatternPreferences.setKeyPatterns(newKeyPattern);
}

public BooleanProperty transliterateFieldsForCitationKeyProperty() {
return transliterateFieldsForCitationKeyProperty;
}

public BooleanProperty overwriteAllowProperty() {
return overwriteAllowProperty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,30 @@
<Label styleClass="sectionHeader" text="%General"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="0"/>

<CheckBox fx:id="transliterateFieldsForCitationKey" text="%Transliterate fields for citation key"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="1"/>


<CheckBox fx:id="overwriteAllow" text="%Overwrite existing keys"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="1"/>
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="2"/>

<HBox styleClass="prefIndent"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="2">
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="3">
<CheckBox fx:id="overwriteWarning"
text="%Warn before overwriting existing keys"
disable="${!overwriteAllow.selected}"/>
</HBox>

<CheckBox fx:id="generateOnSave" text="%Generate keys before saving (for entries without a key)"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="3"/>
<CheckBox fx:id="generateNewKeyOnImport" text="%Generate a new key for imported entries (overwriting their default)"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="4"/>

<CheckBox fx:id="generateNewKeyOnImport" text="%Generate a new key for imported entries (overwriting their default)"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="5"/>

<Label text="%Letters after duplicate generated keys" GridPane.columnIndex="0"
GridPane.columnSpan="3" GridPane.rowIndex="5"/>
GridPane.columnSpan="3" GridPane.rowIndex="6"/>
<VBox spacing="10.0" styleClass="prefIndent"
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="6">
GridPane.columnIndex="0" GridPane.columnSpan="3" GridPane.rowIndex="7">
<RadioButton fx:id="letterStartA"
text="%Start on second duplicate key with letter A (a, b, ...)"
toggleGroup="$uniqueKeyLetters"/>
Expand All @@ -60,20 +67,20 @@
</VBox>

<Label text="%Replace (regular expression)"
GridPane.columnIndex="0" GridPane.rowIndex="7"/>
GridPane.columnIndex="0" GridPane.rowIndex="8"/>
<HBox spacing="4.0" alignment="CENTER_LEFT"
GridPane.columnIndex="1" GridPane.rowIndex="7">
GridPane.columnIndex="1" GridPane.rowIndex="8">
<TextField fx:id="keyPatternRegex" HBox.hgrow="ALWAYS"/>
<Label text="%by"/>
<TextField fx:id="keyPatternReplacement" HBox.hgrow="ALWAYS"/>
</HBox>
<HelpButton helpUrl="https://docs.jabref.org/setup/citationkeypatterns#replace-via-regular-expression"
GridPane.columnIndex="2" GridPane.rowIndex="7"/>
GridPane.columnIndex="2" GridPane.rowIndex="8"/>

<Label text="%Remove the following characters:"
GridPane.columnIndex="0" GridPane.rowIndex="8"/>
GridPane.columnIndex="0" GridPane.rowIndex="9"/>
<TextField fx:id="unwantedCharacters"
GridPane.columnIndex="1" GridPane.rowIndex="8"/>
GridPane.columnIndex="1" GridPane.rowIndex="9"/>
</GridPane>

<HBox spacing="8.0">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ void setUp(@TempDir Path tempDir) {
GuiPreferences guiPreferences = mock(GuiPreferences.class);
filePreferences = mock(FilePreferences.class);
CitationKeyPatternPreferences patternPreferences = new CitationKeyPatternPreferences(
true,
false,
true,
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.regex.PatternSyntaxException;

import org.jabref.logic.util.strings.StringUtil;
import org.jabref.logic.util.strings.Transliteration;
import org.jabref.model.FieldChange;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.database.BibDatabaseContext;
Expand Down Expand Up @@ -37,7 +38,7 @@ public class CitationKeyGenerator extends BracketedPattern {

/// Source of disallowed characters: <https://tex.stackexchange.com/a/408548/9075>
/// These characters are disallowed in BibTeX keys.
private static final List<Character> DISALLOWED_CHARACTERS = Arrays.asList('{', '}', '(', ')', ',', '=', '\\', '"', '#', '%', '~', '\'');
public static final List<Character> DISALLOWED_CHARACTERS = Arrays.asList('{', '}', '(', ')', ',', '=', '\\', '"', '#', '%', '~', '\'');

private static final Logger LOGGER = LoggerFactory.getLogger(CitationKeyGenerator.class);

Expand All @@ -47,9 +48,7 @@ public class CitationKeyGenerator extends BracketedPattern {
private final String unwantedCharacters;

public CitationKeyGenerator(BibDatabaseContext bibDatabaseContext, CitationKeyPatternPreferences citationKeyPatternPreferences) {
this(bibDatabaseContext.getMetaData().getCiteKeyPatterns(citationKeyPatternPreferences.getKeyPatterns()),
bibDatabaseContext.getDatabase(),
citationKeyPatternPreferences);
this(bibDatabaseContext.getMetaData().getCiteKeyPatterns(citationKeyPatternPreferences.getKeyPatterns()), bibDatabaseContext.getDatabase(), citationKeyPatternPreferences);
}

public CitationKeyGenerator(@NonNull AbstractCitationKeyPatterns citeKeyPattern,
Expand Down Expand Up @@ -81,12 +80,7 @@ public static String removeDefaultUnwantedCharacters(String key) {
}

public static String removeUnwantedCharacters(String key, String unwantedCharacters) {
String newKey = key.chars()
.filter(c -> unwantedCharacters.indexOf(c) == -1)
.filter(c -> !DISALLOWED_CHARACTERS.contains((char) c))
.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
String newKey = key.chars().filter(c -> unwantedCharacters.indexOf(c) == -1).filter(c -> !DISALLOWED_CHARACTERS.contains((char) c)).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();

// Replace non-English characters like umlauts etc. with a sensible
// letter or letter combination that bibtex can accept.
Expand All @@ -109,7 +103,8 @@ public String generateKey(@NonNull BibEntry entry) {
String newKey = createCitationKeyFromPattern(entry);
newKey = replaceWithRegex(newKey);
newKey = appendLettersToKey(newKey, currentKey);
return cleanKey(newKey, unwantedCharacters);
newKey = cleanKey(newKey, unwantedCharacters);
return transliterateIfNeeded(newKey);
}

/**
Expand All @@ -126,13 +121,11 @@ private String appendLettersToKey(String key, String oldKey) {
occurrences--; // No change, so we can accept one dupe.
}

boolean alwaysAddLetter = citationKeyPatternPreferences.getKeySuffix()
== CitationKeyPatternPreferences.KeySuffix.ALWAYS;
boolean alwaysAddLetter = citationKeyPatternPreferences.getKeySuffix() == CitationKeyPatternPreferences.KeySuffix.ALWAYS;

if (alwaysAddLetter || occurrences != 0) {
// The key is already in use, so we must modify it.
boolean firstLetterA = citationKeyPatternPreferences.getKeySuffix()
== CitationKeyPatternPreferences.KeySuffix.SECOND_WITH_A;
boolean firstLetterA = citationKeyPatternPreferences.getKeySuffix() == CitationKeyPatternPreferences.KeySuffix.SECOND_WITH_A;

int number = !alwaysAddLetter && !firstLetterA ? 1 : 0;
String moddedKey;
Expand All @@ -155,6 +148,15 @@ private String appendLettersToKey(String key, String oldKey) {
return key;
}

public String transliterateIfNeeded(String key) {
if (!citationKeyPatternPreferences.shouldTransliterateFieldsForCitationKey()) {
return key;
}

String result = Transliteration.transliterate(key);
return result.replace(" ", "");
}

/**
* Using preferences, replace matches to the provided regex with a string.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.jabref.logic.citationkeypattern;

import static org.jabref.logic.citationkeypattern.CitationKeyGenerator.DEFAULT_UNWANTED_CHARACTERS;

public class CitationKeyGeneratorTestUtils {

public static CitationKeyPatternPreferences getInstanceForTesting() {
return new CitationKeyPatternPreferences(
true,
false,
false,
false,
CitationKeyPatternPreferences.KeySuffix.SECOND_WITH_A,
"",
"",
DEFAULT_UNWANTED_CHARACTERS,
GlobalCitationKeyPatterns.fromPattern("[auth][year]"),
"",
','
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum KeySuffix {
SECOND_WITH_B // CiteKey, CiteKeyB, CiteKeyC ...
}

private final BooleanProperty shouldTransliterateFieldsForCitationKey = new SimpleBooleanProperty();
private final BooleanProperty shouldAvoidOverwriteCiteKey = new SimpleBooleanProperty();
private final BooleanProperty shouldWarnBeforeOverwriteCiteKey = new SimpleBooleanProperty();
private final BooleanProperty shouldGenerateCiteKeysBeforeSaving = new SimpleBooleanProperty();
Expand All @@ -29,7 +30,8 @@ public enum KeySuffix {
private final String defaultPattern;
private final ReadOnlyObjectProperty<Character> keywordDelimiter;

public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey,
public CitationKeyPatternPreferences(boolean shouldTransliterateFieldsForCitationKey,
boolean shouldAvoidOverwriteCiteKey,
boolean shouldWarnBeforeOverwriteCiteKey,
boolean shouldGenerateCiteKeysBeforeSaving,
KeySuffix keySuffix,
Expand All @@ -40,6 +42,7 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey,
String defaultPattern,
ReadOnlyObjectProperty<Character> keywordDelimiter) {

this.shouldTransliterateFieldsForCitationKey.set(shouldTransliterateFieldsForCitationKey);
this.shouldAvoidOverwriteCiteKey.set(shouldAvoidOverwriteCiteKey);
this.shouldWarnBeforeOverwriteCiteKey.set(shouldWarnBeforeOverwriteCiteKey);
this.shouldGenerateCiteKeysBeforeSaving.set(shouldGenerateCiteKeysBeforeSaving);
Expand All @@ -54,7 +57,8 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey,
}

@VisibleForTesting
public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey,
public CitationKeyPatternPreferences(boolean shouldTransliterateFieldsForCitationKey,
boolean shouldAvoidOverwriteCiteKey,
boolean shouldWarnBeforeOverwriteCiteKey,
boolean shouldGenerateCiteKeysBeforeSaving,
KeySuffix keySuffix,
Expand All @@ -65,7 +69,8 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey,
String defaultPattern,
Character keywordDelimiter) {

this(shouldAvoidOverwriteCiteKey,
this(shouldTransliterateFieldsForCitationKey,
shouldAvoidOverwriteCiteKey,
shouldWarnBeforeOverwriteCiteKey,
shouldGenerateCiteKeysBeforeSaving,
keySuffix,
Expand All @@ -77,6 +82,18 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey,
new SimpleObjectProperty<>(keywordDelimiter));
}

public boolean shouldTransliterateFieldsForCitationKey() {
return shouldTransliterateFieldsForCitationKey.get();
}

public BooleanProperty shouldTransliterateFieldsForCitationKeyProperty() {
return shouldTransliterateFieldsForCitationKey;
}

public void setShouldTransliterateFieldsForCitationKey(boolean shouldTransliterateFieldsForCitationKey) {
this.shouldTransliterateFieldsForCitationKey.set(shouldTransliterateFieldsForCitationKey);
}

public boolean shouldAvoidOverwriteCiteKey() {
return shouldAvoidOverwriteCiteKey.get();
}
Expand Down
Loading
Loading