From 27f97b50f9fbf354b23db233573f70ede2bc918e Mon Sep 17 00:00:00 2001 From: tushar-2320 Date: Sun, 17 Aug 2025 10:21:21 +0530 Subject: [PATCH 1/4] initial commit --- .../gui/preferences/entry/EntryTab.java | 21 ++++++++----------- .../org/jabref/model/entry/KeywordList.java | 4 ++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/preferences/entry/EntryTab.java b/jabgui/src/main/java/org/jabref/gui/preferences/entry/EntryTab.java index 072d2e6e27b..319ad380df0 100644 --- a/jabgui/src/main/java/org/jabref/gui/preferences/entry/EntryTab.java +++ b/jabgui/src/main/java/org/jabref/gui/preferences/entry/EntryTab.java @@ -1,7 +1,5 @@ package org.jabref.gui.preferences.entry; -import java.util.function.UnaryOperator; - import javafx.css.PseudoClass; import javafx.fxml.FXML; import javafx.scene.Node; @@ -10,7 +8,6 @@ import javafx.scene.control.ContentDisplay; import javafx.scene.control.Label; import javafx.scene.control.TextField; -import javafx.scene.control.TextFormatter; import javafx.scene.input.KeyCode; import org.jabref.gui.actions.ActionFactory; @@ -57,15 +54,15 @@ public void initialize() { keywordSeparator.textProperty().bindBidirectional(viewModel.keywordSeparatorProperty()); // Use TextFormatter to limit the length of the Input of keywordSeparator to 1 character only. - UnaryOperator singleCharacterFilter = change -> { - if (change.getControlNewText().length() <= 1) { - return change; - } - return null; // null means the change is rejected - }; - TextFormatter formatter = new TextFormatter<>(singleCharacterFilter); - - keywordSeparator.setTextFormatter(formatter); +// UnaryOperator singleCharacterFilter = change -> { +// if (change.getControlNewText().length() <= 1) { +// return change; +// } +// return null; // null means the change is rejected +// }; +// TextFormatter formatter = new TextFormatter<>(singleCharacterFilter); + +// keywordSeparator.setTextFormatter(formatter); resolveStrings.selectedProperty().bindBidirectional(viewModel.resolveStringsProperty()); diff --git a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java index 76adb9add8d..d30e96c2c37 100644 --- a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java +++ b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java @@ -53,6 +53,10 @@ public static KeywordList parse(String keywordString, Character delimiter, Chara KeywordList keywordList = new KeywordList(); + for (char d : delimiter.toString().toCharArray()) { + keywordString = keywordString.replace(d, ','); + } + StringTokenizer tok = new StringTokenizer(keywordString, delimiter.toString()); while (tok.hasMoreTokens()) { String chain = tok.nextToken(); From 88fe7f7a2777078cc7dae45822fed26e82ea89e9 Mon Sep 17 00:00:00 2001 From: tushar-2320 Date: Mon, 25 Aug 2025 10:27:15 +0530 Subject: [PATCH 2/4] refactor:converted arguments to string for multiple delimeter. --- .../fieldeditors/KeywordsEditorViewModel.java | 12 ++++--- .../AutoSetFileLinksUtilTest.java | 2 +- .../citationkeypattern/BracketedPattern.java | 33 ++++++++++++++----- .../CitationKeyGenerator.java | 2 +- .../CitationKeyPatternPreferences.java | 8 ++--- .../preferences/JabRefCliPreferences.java | 2 +- .../logic/util/io/AutoLinkPreferences.java | 8 ++--- .../org/jabref/logic/xmp/XmpPreferences.java | 6 ++-- .../model/entry/BibEntryPreferences.java | 10 +++--- .../org/jabref/model/entry/KeywordList.java | 4 --- 10 files changed, 51 insertions(+), 36 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java index 78a7dc650c2..548af1b3ec0 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java @@ -26,7 +26,7 @@ public class KeywordsEditorViewModel extends AbstractEditorViewModel { private static final Logger LOGGER = LoggerFactory.getLogger(KeywordsEditorViewModel.class); private final ListProperty keywordListProperty; - private final Character keywordSeparator; + private final String keywordSeparator; private final SuggestionProvider suggestionProvider; public KeywordsEditorViewModel(Field field, @@ -49,11 +49,15 @@ public KeywordsEditorViewModel(Field field, } private String serializeKeywords(List keywords) { - return KeywordList.serialize(keywords, keywordSeparator); + return KeywordList.serialize(keywords, ','); } private List parseKeywords(String newText) { - return KeywordList.parse(newText, keywordSeparator).stream().toList(); + for (char d : keywordSeparator.toCharArray()) { + newText = newText.replace(d, ','); + } + + return KeywordList.parse(newText, ',').stream().toList(); } public ListProperty keywordListProperty() { @@ -94,7 +98,7 @@ public List getSuggestions(String request) { return suggestions; } - public Character getKeywordSeparator() { + public String getKeywordSeparator() { return keywordSeparator; } } diff --git a/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java b/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java index c964b7d366c..c6fad72a109 100644 --- a/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java +++ b/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java @@ -35,7 +35,7 @@ class AutoSetFileLinksUtilTest { AutoLinkPreferences.CitationKeyDependency.START, "", false, - ';'); + ";"); private final BibDatabaseContext databaseContext = mock(BibDatabaseContext.class); private final BibEntry entry = new BibEntry(StandardEntryType.Article); private Path path = null; diff --git a/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java b/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java index 3e1f0e61ba8..89bfee3cca9 100644 --- a/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java +++ b/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java @@ -165,7 +165,7 @@ public String expand(BibEntry bibentry) { */ public String expand(BibEntry bibentry, BibDatabase database) { Objects.requireNonNull(bibentry); - Character keywordDelimiter = ';'; + String keywordDelimiter = ";"; return expand(bibentry, keywordDelimiter, database); } @@ -177,7 +177,7 @@ public String expand(BibEntry bibentry, BibDatabase database) { * @param database The database to use for string-lookups and cross-refs. May be null. * @return The expanded pattern. The empty string is returned, if it could not be expanded. */ - public String expand(BibEntry bibentry, Character keywordDelimiter, BibDatabase database) { + public String expand(BibEntry bibentry, String keywordDelimiter, BibDatabase database) { Objects.requireNonNull(bibentry); return expandBrackets(this.pattern, keywordDelimiter, bibentry, database); } @@ -191,7 +191,7 @@ public String expand(BibEntry bibentry, Character keywordDelimiter, BibDatabase * @param database The database for field resolving. May be null. * @return The expanded pattern. Not null. */ - public static String expandBrackets(String pattern, Character keywordDelimiter, BibEntry entry, BibDatabase database) { + public static String expandBrackets(String pattern, String keywordDelimiter, BibEntry entry, BibDatabase database) { Objects.requireNonNull(pattern); Objects.requireNonNull(entry); return expandBrackets(pattern, expandBracketContent(keywordDelimiter, entry, database)); @@ -206,7 +206,7 @@ public static String expandBrackets(String pattern, Character keywordDelimiter, * @param database The {@link BibDatabase} for field resolving. May be null. * @return a function accepting a bracketed expression and returning the result of expanding it */ - public static Function expandBracketContent(Character keywordDelimiter, BibEntry entry, BibDatabase database) { + public static Function expandBracketContent(String keywordDelimiter, BibEntry entry, BibDatabase database) { return (String bracket) -> { List fieldParts = parseFieldAndModifiers(bracket); // check whether there is a modifier on the end such as @@ -259,7 +259,7 @@ public static String expandBrackets(String pattern, Function bra /** * Returns the content enclosed between brackets, including enclosed quotes, and excluding the paired enclosing brackets. * There may be brackets in it. - * Intended to be used by {@link BracketedPattern#expandBrackets(String, Character, BibEntry, BibDatabase)} when a [ + * Intended to be used by {@link BracketedPattern#expandBrackets(String, String, BibEntry, BibDatabase)} when a [ * is encountered, and has been consumed, by the {@code StringTokenizer}. * * @param pattern pattern used by {@code expandBrackets}, used for logging @@ -302,7 +302,7 @@ private static String contentBetweenBrackets(StringTokenizer tokenizer, final St /** * Appends the content between, and including, two \" to the provided StringBuilder. Intended to be - * used by {@link BracketedPattern#expandBrackets(String, Character, BibEntry, BibDatabase)} when a \" is + * used by {@link BracketedPattern#expandBrackets(String, String, BibEntry, BibDatabase)} when a \" is * encountered by the StringTokenizer. * * @param stringBuilder the StringBuilder to which tokens will be appended @@ -326,7 +326,7 @@ private static void appendQuote(StringBuilder stringBuilder, StringTokenizer tok * @param database The database to use for field resolving. May be null. * @return String containing the evaluation result. Empty string if the pattern cannot be resolved. */ - public static String getFieldValue(BibEntry entry, String pattern, Character keywordDelimiter, BibDatabase database) { + public static String getFieldValue(BibEntry entry, String pattern, String keywordDelimiter, BibDatabase database) { try { if (pattern.startsWith("auth") || pattern.startsWith("pureauth")) { // result the author @@ -481,7 +481,15 @@ public static String getFieldValue(BibEntry entry, String pattern, Character key } else if (pattern.matches("keyword\\d+")) { // according to LabelPattern.php, it returns keyword number n int num = Integer.parseInt(pattern.substring(7)); - KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); + // KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); + + Optional keywordsContent = entry.getResolvedFieldOrAlias(StandardField.KEYWORDS, database); + + for (char d : keywordDelimiter.toCharArray()) { + keywordsContent = keywordsContent.map(content -> content.replace(d, ',')); + } + KeywordList separatedKeywords = keywordsContent.map(content -> KeywordList.parse(content, ',')).orElse(new KeywordList()); + if (separatedKeywords.size() < num) { // not enough keywords return ""; @@ -497,7 +505,14 @@ public static String getFieldValue(BibEntry entry, String pattern, Character key } else { num = Integer.MAX_VALUE; } - KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); +// KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); + Optional keywordsContent = entry.getResolvedFieldOrAlias(StandardField.KEYWORDS, database); + + for (char d : keywordDelimiter.toCharArray()) { + keywordsContent = keywordsContent.map(content -> content.replace(d, ',')); + } + KeywordList separatedKeywords = keywordsContent.map(content -> KeywordList.parse(content, ',')).orElse(new KeywordList()); + StringBuilder sb = new StringBuilder(); int i = 0; for (Keyword keyword : separatedKeywords) { diff --git a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java index 2e091d568dd..a8d88a9ca03 100644 --- a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java +++ b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java @@ -188,7 +188,7 @@ private String createCitationKeyFromPattern(BibEntry entry) { * @return a cleaned citation key for the given {@link BibEntry} */ private Function expandBracketContent(BibEntry entry) { - Character keywordDelimiter = citationKeyPatternPreferences.getKeywordDelimiter(); + String keywordDelimiter = citationKeyPatternPreferences.getKeywordDelimiter(); return (String bracket) -> { String expandedPattern; diff --git a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java index 200fc352ead..887870fe986 100644 --- a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java @@ -27,7 +27,7 @@ public enum KeySuffix { private final StringProperty unwantedCharacters = new SimpleStringProperty(); private final ObjectProperty keyPatterns = new SimpleObjectProperty<>(); private final String defaultPattern; - private final ReadOnlyObjectProperty keywordDelimiter; + private final ReadOnlyObjectProperty keywordDelimiter; public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey, boolean shouldWarnBeforeOverwriteCiteKey, @@ -38,7 +38,7 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey, String unwantedCharacters, GlobalCitationKeyPatterns keyPatterns, String defaultPattern, - ReadOnlyObjectProperty keywordDelimiter) { + ReadOnlyObjectProperty keywordDelimiter) { this.shouldAvoidOverwriteCiteKey.set(shouldAvoidOverwriteCiteKey); this.shouldWarnBeforeOverwriteCiteKey.set(shouldWarnBeforeOverwriteCiteKey); @@ -63,7 +63,7 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey, String unwantedCharacters, GlobalCitationKeyPatterns keyPatterns, String defaultPattern, - Character keywordDelimiter) { + String keywordDelimiter) { this(shouldAvoidOverwriteCiteKey, shouldWarnBeforeOverwriteCiteKey, @@ -177,7 +177,7 @@ public String getDefaultPattern() { return defaultPattern; } - public Character getKeywordDelimiter() { + public String getKeywordDelimiter() { return keywordDelimiter.get(); } } diff --git a/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java b/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java index 6fa4554cbb4..db129b0e140 100644 --- a/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java @@ -1573,7 +1573,7 @@ public BibEntryPreferences getBibEntryPreferences() { } bibEntryPreferences = new BibEntryPreferences( - get(KEYWORD_SEPARATOR).charAt(0) + get(KEYWORD_SEPARATOR) ); EasyBind.listen(bibEntryPreferences.keywordSeparatorProperty(), (_, _, newValue) -> put(KEYWORD_SEPARATOR, String.valueOf(newValue))); diff --git a/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java b/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java index 94c2b620ec9..51949054399 100644 --- a/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java @@ -19,12 +19,12 @@ public enum CitationKeyDependency { private final ObjectProperty citationKeyDependency; private final StringProperty regularExpression; private final BooleanProperty askAutoNamingPdfs; - private final ReadOnlyObjectProperty keywordSeparator; + private final ReadOnlyObjectProperty keywordSeparator; public AutoLinkPreferences(CitationKeyDependency citationKeyDependency, String regularExpression, boolean askAutoNamingPdfs, - ObjectProperty keywordSeparatorProperty) { + ObjectProperty keywordSeparatorProperty) { this.citationKeyDependency = new SimpleObjectProperty<>(citationKeyDependency); this.regularExpression = new SimpleStringProperty(regularExpression); this.askAutoNamingPdfs = new SimpleBooleanProperty(askAutoNamingPdfs); @@ -37,7 +37,7 @@ public AutoLinkPreferences(CitationKeyDependency citationKeyDependency, public AutoLinkPreferences(CitationKeyDependency citationKeyDependency, String regularExpression, boolean askAutoNamingPdfs, - Character keywordSeparator) { + String keywordSeparator) { this.citationKeyDependency = new SimpleObjectProperty<>(citationKeyDependency); this.regularExpression = new SimpleStringProperty(regularExpression); this.askAutoNamingPdfs = new SimpleBooleanProperty(askAutoNamingPdfs); @@ -80,7 +80,7 @@ public void setAskAutoNamingPdfs(boolean askAutoNamingPdfs) { this.askAutoNamingPdfs.set(askAutoNamingPdfs); } - public Character getKeywordSeparator() { + public String getKeywordSeparator() { return keywordSeparator.getValue(); } } diff --git a/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java b/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java index 136bb06e2f1..57f68ff28fb 100644 --- a/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java @@ -14,9 +14,9 @@ public class XmpPreferences { private final BooleanProperty useXmpPrivacyFilter; private final ObservableSet xmpPrivacyFilter; - private final ObjectProperty keywordSeparator; + private final ObjectProperty keywordSeparator; - public XmpPreferences(boolean useXmpPrivacyFilter, Set xmpPrivacyFilter, ObjectProperty keywordSeparator) { + public XmpPreferences(boolean useXmpPrivacyFilter, Set xmpPrivacyFilter, ObjectProperty keywordSeparator) { this.useXmpPrivacyFilter = new SimpleBooleanProperty(useXmpPrivacyFilter); this.xmpPrivacyFilter = FXCollections.observableSet(xmpPrivacyFilter); this.keywordSeparator = keywordSeparator; @@ -38,7 +38,7 @@ public ObservableSet getXmpPrivacyFilter() { return xmpPrivacyFilter; } - public Character getKeywordSeparator() { + public String getKeywordSeparator() { return keywordSeparator.getValue(); } } diff --git a/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java b/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java index 1e2caadc856..9ce654e3be1 100644 --- a/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java +++ b/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java @@ -4,21 +4,21 @@ import javafx.beans.property.SimpleObjectProperty; public class BibEntryPreferences { - private final ObjectProperty keywordSeparator; + private final ObjectProperty keywordSeparator; - public BibEntryPreferences(Character keywordSeparator) { + public BibEntryPreferences(String keywordSeparator) { this.keywordSeparator = new SimpleObjectProperty<>(keywordSeparator); } - public Character getKeywordSeparator() { + public String getKeywordSeparator() { return keywordSeparator.get(); } - public ObjectProperty keywordSeparatorProperty() { + public ObjectProperty keywordSeparatorProperty() { return keywordSeparator; } - public void setKeywordSeparator(Character keywordSeparator) { + public void setKeywordSeparator(String keywordSeparator) { this.keywordSeparator.set(keywordSeparator); } } diff --git a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java index d30e96c2c37..76adb9add8d 100644 --- a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java +++ b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java @@ -53,10 +53,6 @@ public static KeywordList parse(String keywordString, Character delimiter, Chara KeywordList keywordList = new KeywordList(); - for (char d : delimiter.toString().toCharArray()) { - keywordString = keywordString.replace(d, ','); - } - StringTokenizer tok = new StringTokenizer(keywordString, delimiter.toString()); while (tok.hasMoreTokens()) { String chain = tok.nextToken(); From 729e2dccb658a4978c518eb42e4013820a84a229 Mon Sep 17 00:00:00 2001 From: tushar-2320 Date: Wed, 27 Aug 2025 19:38:35 +0530 Subject: [PATCH 3/4] Revert "refactor:converted arguments to string for multiple delimeter." This reverts commit 88fe7f7a2777078cc7dae45822fed26e82ea89e9. --- .../fieldeditors/KeywordsEditorViewModel.java | 12 +++---- .../AutoSetFileLinksUtilTest.java | 2 +- .../citationkeypattern/BracketedPattern.java | 33 +++++-------------- .../CitationKeyGenerator.java | 2 +- .../CitationKeyPatternPreferences.java | 8 ++--- .../preferences/JabRefCliPreferences.java | 2 +- .../logic/util/io/AutoLinkPreferences.java | 8 ++--- .../org/jabref/logic/xmp/XmpPreferences.java | 6 ++-- .../model/entry/BibEntryPreferences.java | 10 +++--- .../org/jabref/model/entry/KeywordList.java | 4 +++ 10 files changed, 36 insertions(+), 51 deletions(-) diff --git a/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java b/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java index 548af1b3ec0..78a7dc650c2 100644 --- a/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java +++ b/jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java @@ -26,7 +26,7 @@ public class KeywordsEditorViewModel extends AbstractEditorViewModel { private static final Logger LOGGER = LoggerFactory.getLogger(KeywordsEditorViewModel.class); private final ListProperty keywordListProperty; - private final String keywordSeparator; + private final Character keywordSeparator; private final SuggestionProvider suggestionProvider; public KeywordsEditorViewModel(Field field, @@ -49,15 +49,11 @@ public KeywordsEditorViewModel(Field field, } private String serializeKeywords(List keywords) { - return KeywordList.serialize(keywords, ','); + return KeywordList.serialize(keywords, keywordSeparator); } private List parseKeywords(String newText) { - for (char d : keywordSeparator.toCharArray()) { - newText = newText.replace(d, ','); - } - - return KeywordList.parse(newText, ',').stream().toList(); + return KeywordList.parse(newText, keywordSeparator).stream().toList(); } public ListProperty keywordListProperty() { @@ -98,7 +94,7 @@ public List getSuggestions(String request) { return suggestions; } - public String getKeywordSeparator() { + public Character getKeywordSeparator() { return keywordSeparator; } } diff --git a/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java b/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java index c6fad72a109..c964b7d366c 100644 --- a/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java +++ b/jabgui/src/test/java/org/jabref/gui/externalfiles/AutoSetFileLinksUtilTest.java @@ -35,7 +35,7 @@ class AutoSetFileLinksUtilTest { AutoLinkPreferences.CitationKeyDependency.START, "", false, - ";"); + ';'); private final BibDatabaseContext databaseContext = mock(BibDatabaseContext.class); private final BibEntry entry = new BibEntry(StandardEntryType.Article); private Path path = null; diff --git a/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java b/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java index 89bfee3cca9..3e1f0e61ba8 100644 --- a/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java +++ b/jablib/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java @@ -165,7 +165,7 @@ public String expand(BibEntry bibentry) { */ public String expand(BibEntry bibentry, BibDatabase database) { Objects.requireNonNull(bibentry); - String keywordDelimiter = ";"; + Character keywordDelimiter = ';'; return expand(bibentry, keywordDelimiter, database); } @@ -177,7 +177,7 @@ public String expand(BibEntry bibentry, BibDatabase database) { * @param database The database to use for string-lookups and cross-refs. May be null. * @return The expanded pattern. The empty string is returned, if it could not be expanded. */ - public String expand(BibEntry bibentry, String keywordDelimiter, BibDatabase database) { + public String expand(BibEntry bibentry, Character keywordDelimiter, BibDatabase database) { Objects.requireNonNull(bibentry); return expandBrackets(this.pattern, keywordDelimiter, bibentry, database); } @@ -191,7 +191,7 @@ public String expand(BibEntry bibentry, String keywordDelimiter, BibDatabase dat * @param database The database for field resolving. May be null. * @return The expanded pattern. Not null. */ - public static String expandBrackets(String pattern, String keywordDelimiter, BibEntry entry, BibDatabase database) { + public static String expandBrackets(String pattern, Character keywordDelimiter, BibEntry entry, BibDatabase database) { Objects.requireNonNull(pattern); Objects.requireNonNull(entry); return expandBrackets(pattern, expandBracketContent(keywordDelimiter, entry, database)); @@ -206,7 +206,7 @@ public static String expandBrackets(String pattern, String keywordDelimiter, Bib * @param database The {@link BibDatabase} for field resolving. May be null. * @return a function accepting a bracketed expression and returning the result of expanding it */ - public static Function expandBracketContent(String keywordDelimiter, BibEntry entry, BibDatabase database) { + public static Function expandBracketContent(Character keywordDelimiter, BibEntry entry, BibDatabase database) { return (String bracket) -> { List fieldParts = parseFieldAndModifiers(bracket); // check whether there is a modifier on the end such as @@ -259,7 +259,7 @@ public static String expandBrackets(String pattern, Function bra /** * Returns the content enclosed between brackets, including enclosed quotes, and excluding the paired enclosing brackets. * There may be brackets in it. - * Intended to be used by {@link BracketedPattern#expandBrackets(String, String, BibEntry, BibDatabase)} when a [ + * Intended to be used by {@link BracketedPattern#expandBrackets(String, Character, BibEntry, BibDatabase)} when a [ * is encountered, and has been consumed, by the {@code StringTokenizer}. * * @param pattern pattern used by {@code expandBrackets}, used for logging @@ -302,7 +302,7 @@ private static String contentBetweenBrackets(StringTokenizer tokenizer, final St /** * Appends the content between, and including, two \" to the provided StringBuilder. Intended to be - * used by {@link BracketedPattern#expandBrackets(String, String, BibEntry, BibDatabase)} when a \" is + * used by {@link BracketedPattern#expandBrackets(String, Character, BibEntry, BibDatabase)} when a \" is * encountered by the StringTokenizer. * * @param stringBuilder the StringBuilder to which tokens will be appended @@ -326,7 +326,7 @@ private static void appendQuote(StringBuilder stringBuilder, StringTokenizer tok * @param database The database to use for field resolving. May be null. * @return String containing the evaluation result. Empty string if the pattern cannot be resolved. */ - public static String getFieldValue(BibEntry entry, String pattern, String keywordDelimiter, BibDatabase database) { + public static String getFieldValue(BibEntry entry, String pattern, Character keywordDelimiter, BibDatabase database) { try { if (pattern.startsWith("auth") || pattern.startsWith("pureauth")) { // result the author @@ -481,15 +481,7 @@ public static String getFieldValue(BibEntry entry, String pattern, String keywor } else if (pattern.matches("keyword\\d+")) { // according to LabelPattern.php, it returns keyword number n int num = Integer.parseInt(pattern.substring(7)); - // KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); - - Optional keywordsContent = entry.getResolvedFieldOrAlias(StandardField.KEYWORDS, database); - - for (char d : keywordDelimiter.toCharArray()) { - keywordsContent = keywordsContent.map(content -> content.replace(d, ',')); - } - KeywordList separatedKeywords = keywordsContent.map(content -> KeywordList.parse(content, ',')).orElse(new KeywordList()); - + KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); if (separatedKeywords.size() < num) { // not enough keywords return ""; @@ -505,14 +497,7 @@ public static String getFieldValue(BibEntry entry, String pattern, String keywor } else { num = Integer.MAX_VALUE; } -// KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); - Optional keywordsContent = entry.getResolvedFieldOrAlias(StandardField.KEYWORDS, database); - - for (char d : keywordDelimiter.toCharArray()) { - keywordsContent = keywordsContent.map(content -> content.replace(d, ',')); - } - KeywordList separatedKeywords = keywordsContent.map(content -> KeywordList.parse(content, ',')).orElse(new KeywordList()); - + KeywordList separatedKeywords = entry.getResolvedKeywords(keywordDelimiter, database); StringBuilder sb = new StringBuilder(); int i = 0; for (Keyword keyword : separatedKeywords) { diff --git a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java index a8d88a9ca03..2e091d568dd 100644 --- a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java +++ b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java @@ -188,7 +188,7 @@ private String createCitationKeyFromPattern(BibEntry entry) { * @return a cleaned citation key for the given {@link BibEntry} */ private Function expandBracketContent(BibEntry entry) { - String keywordDelimiter = citationKeyPatternPreferences.getKeywordDelimiter(); + Character keywordDelimiter = citationKeyPatternPreferences.getKeywordDelimiter(); return (String bracket) -> { String expandedPattern; diff --git a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java index 887870fe986..200fc352ead 100644 --- a/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyPatternPreferences.java @@ -27,7 +27,7 @@ public enum KeySuffix { private final StringProperty unwantedCharacters = new SimpleStringProperty(); private final ObjectProperty keyPatterns = new SimpleObjectProperty<>(); private final String defaultPattern; - private final ReadOnlyObjectProperty keywordDelimiter; + private final ReadOnlyObjectProperty keywordDelimiter; public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey, boolean shouldWarnBeforeOverwriteCiteKey, @@ -38,7 +38,7 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey, String unwantedCharacters, GlobalCitationKeyPatterns keyPatterns, String defaultPattern, - ReadOnlyObjectProperty keywordDelimiter) { + ReadOnlyObjectProperty keywordDelimiter) { this.shouldAvoidOverwriteCiteKey.set(shouldAvoidOverwriteCiteKey); this.shouldWarnBeforeOverwriteCiteKey.set(shouldWarnBeforeOverwriteCiteKey); @@ -63,7 +63,7 @@ public CitationKeyPatternPreferences(boolean shouldAvoidOverwriteCiteKey, String unwantedCharacters, GlobalCitationKeyPatterns keyPatterns, String defaultPattern, - String keywordDelimiter) { + Character keywordDelimiter) { this(shouldAvoidOverwriteCiteKey, shouldWarnBeforeOverwriteCiteKey, @@ -177,7 +177,7 @@ public String getDefaultPattern() { return defaultPattern; } - public String getKeywordDelimiter() { + public Character getKeywordDelimiter() { return keywordDelimiter.get(); } } diff --git a/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java b/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java index db129b0e140..6fa4554cbb4 100644 --- a/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java @@ -1573,7 +1573,7 @@ public BibEntryPreferences getBibEntryPreferences() { } bibEntryPreferences = new BibEntryPreferences( - get(KEYWORD_SEPARATOR) + get(KEYWORD_SEPARATOR).charAt(0) ); EasyBind.listen(bibEntryPreferences.keywordSeparatorProperty(), (_, _, newValue) -> put(KEYWORD_SEPARATOR, String.valueOf(newValue))); diff --git a/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java b/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java index 51949054399..94c2b620ec9 100644 --- a/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/util/io/AutoLinkPreferences.java @@ -19,12 +19,12 @@ public enum CitationKeyDependency { private final ObjectProperty citationKeyDependency; private final StringProperty regularExpression; private final BooleanProperty askAutoNamingPdfs; - private final ReadOnlyObjectProperty keywordSeparator; + private final ReadOnlyObjectProperty keywordSeparator; public AutoLinkPreferences(CitationKeyDependency citationKeyDependency, String regularExpression, boolean askAutoNamingPdfs, - ObjectProperty keywordSeparatorProperty) { + ObjectProperty keywordSeparatorProperty) { this.citationKeyDependency = new SimpleObjectProperty<>(citationKeyDependency); this.regularExpression = new SimpleStringProperty(regularExpression); this.askAutoNamingPdfs = new SimpleBooleanProperty(askAutoNamingPdfs); @@ -37,7 +37,7 @@ public AutoLinkPreferences(CitationKeyDependency citationKeyDependency, public AutoLinkPreferences(CitationKeyDependency citationKeyDependency, String regularExpression, boolean askAutoNamingPdfs, - String keywordSeparator) { + Character keywordSeparator) { this.citationKeyDependency = new SimpleObjectProperty<>(citationKeyDependency); this.regularExpression = new SimpleStringProperty(regularExpression); this.askAutoNamingPdfs = new SimpleBooleanProperty(askAutoNamingPdfs); @@ -80,7 +80,7 @@ public void setAskAutoNamingPdfs(boolean askAutoNamingPdfs) { this.askAutoNamingPdfs.set(askAutoNamingPdfs); } - public String getKeywordSeparator() { + public Character getKeywordSeparator() { return keywordSeparator.getValue(); } } diff --git a/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java b/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java index 57f68ff28fb..136bb06e2f1 100644 --- a/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java +++ b/jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java @@ -14,9 +14,9 @@ public class XmpPreferences { private final BooleanProperty useXmpPrivacyFilter; private final ObservableSet xmpPrivacyFilter; - private final ObjectProperty keywordSeparator; + private final ObjectProperty keywordSeparator; - public XmpPreferences(boolean useXmpPrivacyFilter, Set xmpPrivacyFilter, ObjectProperty keywordSeparator) { + public XmpPreferences(boolean useXmpPrivacyFilter, Set xmpPrivacyFilter, ObjectProperty keywordSeparator) { this.useXmpPrivacyFilter = new SimpleBooleanProperty(useXmpPrivacyFilter); this.xmpPrivacyFilter = FXCollections.observableSet(xmpPrivacyFilter); this.keywordSeparator = keywordSeparator; @@ -38,7 +38,7 @@ public ObservableSet getXmpPrivacyFilter() { return xmpPrivacyFilter; } - public String getKeywordSeparator() { + public Character getKeywordSeparator() { return keywordSeparator.getValue(); } } diff --git a/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java b/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java index 9ce654e3be1..1e2caadc856 100644 --- a/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java +++ b/jablib/src/main/java/org/jabref/model/entry/BibEntryPreferences.java @@ -4,21 +4,21 @@ import javafx.beans.property.SimpleObjectProperty; public class BibEntryPreferences { - private final ObjectProperty keywordSeparator; + private final ObjectProperty keywordSeparator; - public BibEntryPreferences(String keywordSeparator) { + public BibEntryPreferences(Character keywordSeparator) { this.keywordSeparator = new SimpleObjectProperty<>(keywordSeparator); } - public String getKeywordSeparator() { + public Character getKeywordSeparator() { return keywordSeparator.get(); } - public ObjectProperty keywordSeparatorProperty() { + public ObjectProperty keywordSeparatorProperty() { return keywordSeparator; } - public void setKeywordSeparator(String keywordSeparator) { + public void setKeywordSeparator(Character keywordSeparator) { this.keywordSeparator.set(keywordSeparator); } } diff --git a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java index 76adb9add8d..d30e96c2c37 100644 --- a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java +++ b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java @@ -53,6 +53,10 @@ public static KeywordList parse(String keywordString, Character delimiter, Chara KeywordList keywordList = new KeywordList(); + for (char d : delimiter.toString().toCharArray()) { + keywordString = keywordString.replace(d, ','); + } + StringTokenizer tok = new StringTokenizer(keywordString, delimiter.toString()); while (tok.hasMoreTokens()) { String chain = tok.nextToken(); From 37bd7e2f099a8327f16412fa411aec281de45354 Mon Sep 17 00:00:00 2001 From: tushar-2320 Date: Tue, 2 Sep 2025 10:26:25 +0530 Subject: [PATCH 4/4] fix:created new method for parsing with multiple delimeter. --- .../org/jabref/model/entry/KeywordList.java | 27 ++++++++++++++++--- .../jabref/model/entry/KeywordListTest.java | 6 +++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java index d30e96c2c37..cd6b08031ed 100644 --- a/jablib/src/main/java/org/jabref/model/entry/KeywordList.java +++ b/jablib/src/main/java/org/jabref/model/entry/KeywordList.java @@ -53,11 +53,28 @@ public static KeywordList parse(String keywordString, Character delimiter, Chara KeywordList keywordList = new KeywordList(); - for (char d : delimiter.toString().toCharArray()) { - keywordString = keywordString.replace(d, ','); + StringTokenizer tok = new StringTokenizer(keywordString, delimiter.toString()); + while (tok.hasMoreTokens()) { + String chain = tok.nextToken(); + Keyword chainRoot = Keyword.of(chain.split(hierarchicalDelimiter.toString())); + keywordList.add(chainRoot); } + return keywordList; + } - StringTokenizer tok = new StringTokenizer(keywordString, delimiter.toString()); + public static KeywordList parseMultipleDelimiter(String keywordString, String delimiter, Character hierarchicalDelimiter) { + if (StringUtil.isBlank(keywordString)) { + return new KeywordList(); + } + + Objects.requireNonNull(delimiter); + Objects.requireNonNull(hierarchicalDelimiter); + + KeywordList keywordList = new KeywordList(); + for (char d:delimiter.toCharArray()) { + keywordString = keywordString.replace(d, ','); + } + StringTokenizer tok = new StringTokenizer(keywordString, ","); while (tok.hasMoreTokens()) { String chain = tok.nextToken(); Keyword chainRoot = Keyword.of(chain.split(hierarchicalDelimiter.toString())); @@ -77,6 +94,10 @@ public static KeywordList parse(String keywordString, Character delimiter) { return parse(keywordString, delimiter, Keyword.DEFAULT_HIERARCHICAL_DELIMITER); } + public static KeywordList parseMultipleDelimeter(String keywordString, String delimiter) { + return parseMultipleDelimiter(keywordString, delimiter, Keyword.DEFAULT_HIERARCHICAL_DELIMITER); + } + public static String serialize(List keywords, Character delimiter) { return keywords.stream().map(Keyword::get).collect(Collectors.joining(delimiter.toString())); } diff --git a/jablib/src/test/java/org/jabref/model/entry/KeywordListTest.java b/jablib/src/test/java/org/jabref/model/entry/KeywordListTest.java index 033d2c26615..b4bd78bb1d1 100644 --- a/jablib/src/test/java/org/jabref/model/entry/KeywordListTest.java +++ b/jablib/src/test/java/org/jabref/model/entry/KeywordListTest.java @@ -115,4 +115,10 @@ void mergeTwoDistinctKeywordsShouldReturnTheTwoKeywordsMerged() { void mergeTwoListsOfKeywordsShouldReturnTheKeywordsMerged() { assertEquals(new KeywordList("Figma", "Adobe", "JabRef", "Eclipse", "JetBrains"), KeywordList.merge("Figma, Adobe, JetBrains, Eclipse", "Adobe, JabRef", ',')); } + + @Test + void parseMultipleDelimiter() { + assertEquals(new KeywordList("keywordOne", "keywordTwo", "keywordThree"), + KeywordList.parseMultipleDelimeter("keywordOne; keywordTwo: keywordThree", ";:")); + } }