From 42d2a8d95ce7f282579aa1892bcb534093365c6c Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 05:01:04 +0530 Subject: [PATCH 01/94] Handle numbers for one instance --- .../oocsltext/CSLCitationOOAdapter.java | 88 ++++++++++++++++++- src/main/resources/csl-styles | 2 +- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 51e984523be..6a4e215d5ba 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,7 +1,14 @@ package org.jabref.logic.openoffice.oocsltext; import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; @@ -18,19 +25,30 @@ import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import org.apache.commons.text.StringEscapeUtils; +import org.tinylog.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; public class CSLCitationOOAdapter { private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; + private final List citedEntries = new ArrayList<>(); + private int lastCitationNumber = 0; + private boolean isNumericStyle = false; public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws IllegalArgumentException, WrappedTargetException, CreationException { String style = selectedStyle.getSource(); + isNumericStyle = checkIfNumericStyle(style); List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); + if (isNumericStyle) { + citations = updateCitationNumbers(citations, entries); + } - for (String citation: citations) { + for (String citation : citations) { writeCitation(doc, cursor, citation); } } @@ -41,12 +59,78 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se String style = selectedStyle.getSource(); String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); + if (isNumericStyle) { + inTextCitation = updateCitationNumbers(List.of(inTextCitation), entries).getFirst(); + } writeCitation(doc, cursor, inTextCitation); } - private void writeCitation(XTextDocument doc, XTextCursor cursor, String citation) throws WrappedTargetException, CreationException { + private List updateCitationNumbers(List citations, List entries) { + List updatedCitations = new ArrayList<>(); + for (int i = 0; i < citations.size(); i++) { + updatedCitations.add(updateSingleCitation(citations.get(i), entries)); + } + return updatedCitations; + } + + private String updateSingleCitation(String citation, List entries) { + Pattern pattern = Pattern.compile("(\\[?)(\\d+)(\\]?)(\\.)?(\\s*)"); + Matcher matcher = pattern.matcher(citation); + StringBuilder sb = new StringBuilder(); + + while (matcher.find()) { + try { + int index = Integer.parseInt(matcher.group(2)) - 1; + if (index >= 0 && index < entries.size()) { + BibEntry currentEntry = entries.get(index); + if (!citedEntries.contains(currentEntry)) { + lastCitationNumber++; + citedEntries.add(currentEntry); + } + int currentNumber = citedEntries.indexOf(currentEntry) + 1; + + String prefix = matcher.group(1); + String suffix = matcher.group(3); + String dot = matcher.group(4) != null ? "." : ""; + String space = matcher.group(5); + + String replacement = prefix + currentNumber + suffix + dot + space; + matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); + } else { + // If the index is out of bounds, append the original match + matcher.appendReplacement(sb, matcher.group()); + } + } catch (NumberFormatException e) { + // If parsing fails, append the original match + matcher.appendReplacement(sb, matcher.group()); + Logger.warn("Failed to parse citation number: " + matcher.group(2)); + } + } + matcher.appendTail(sb); + + return sb.toString(); + } + private boolean checkIfNumericStyle(String styleXml) { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(styleXml))); + + Element styleElement = doc.getDocumentElement(); + Element infoElement = (Element) styleElement.getElementsByTagName("info").item(0); + Element categoryElement = (Element) infoElement.getElementsByTagName("category").item(0); + + String citationFormat = categoryElement.getAttribute("citation-format"); + return "numeric".equals(citationFormat); + } catch (Exception e) { + Logger.error("Error parsing CSL style XML", e); + return false; + } + } + + private void writeCitation(XTextDocument doc, XTextCursor cursor, String citation) throws WrappedTargetException, CreationException { String formattedCitation = transformHtml(citation); OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); OOTextIntoOO.write(doc, cursor, ooText); diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index e111543b181..bf2926b71a9 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit e111543b181950a1db5d4fcf91d50467eb825925 +Subproject commit bf2926b71a969644ce735760977d1246aed1f2e2 From caedc3a9c75d67418d0342d85e07ac038d24f55c Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 05:43:16 +0530 Subject: [PATCH 02/94] Use reference marks --- .../org/jabref/gui/openoffice/OOBibBase.java | 21 +-- .../oocsltext/CSLCitationOOAdapter.java | 132 +++++++----------- .../openoffice/oocsltext/MarkManager.java | 87 ++++++++++++ .../openoffice/oocsltext/ReferenceMark.java | 43 ++++++ 4 files changed, 190 insertions(+), 93 deletions(-) create mode 100644 src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java create mode 100644 src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index b1849f8cf2e..70fb6ca2cbe 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -1,6 +1,5 @@ package org.jabref.gui.openoffice; -import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -73,7 +72,7 @@ class OOBibBase { private final OOBibBaseConnect connection; - private final CSLCitationOOAdapter cslCitationOOAdapter; + private CSLCitationOOAdapter cslCitationOOAdapter; public OOBibBase(Path loPath, DialogService dialogService) throws @@ -85,8 +84,6 @@ public OOBibBase(Path loPath, DialogService dialogService) this.refreshBibliographyDuringSyncWhenCiting = false; this.alwaysAddCitedOnPages = false; - - cslCitationOOAdapter = new CSLCitationOOAdapter(); } public void guiActionSelectDocument(boolean autoSelectForSingle) { @@ -593,6 +590,7 @@ public void guiActionInsertEntry(List entries, try { UnoUndo.enterUndoContext(doc, "Insert citation"); if (style instanceof CitationStyle citationStyle) { + CSLCitationOOAdapter adapter = getOrCreateCSLCitationOOAdapter(doc); // Handle insertion of CSL Style citations if (citationType == CitationType.AUTHORYEAR_INTEXT) { cslCitationOOAdapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); @@ -618,12 +616,8 @@ public void guiActionInsertEntry(List entries, OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); } catch (DisposedException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); - } catch (CreationException - | WrappedTargetException - | IOException - | PropertyVetoException - | IllegalTypeException - | NotRemoveableException ex) { + } catch ( + Exception ex) { LOGGER.warn("Could not insert entry", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } finally { @@ -879,4 +873,11 @@ public void guiActionUpdateDocument(List databases, OOStyle style) } } } + + private CSLCitationOOAdapter getOrCreateCSLCitationOOAdapter(XTextDocument doc) throws Exception { + if (cslCitationOOAdapter == null) { + cslCitationOOAdapter = new CSLCitationOOAdapter(doc); + } + return cslCitationOOAdapter; + } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 6a4e215d5ba..6db9666f8d6 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -4,8 +4,7 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.Random; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -18,7 +17,6 @@ import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; -import org.jabref.model.openoffice.ootext.OOTextIntoOO; import org.jabref.model.openoffice.uno.CreationException; import com.sun.star.lang.WrappedTargetException; @@ -32,10 +30,18 @@ public class CSLCitationOOAdapter { + public static final String[] PREFIXES = {"JABREF_", "CSL_"}; + public static final int REFMARK_ADD_CHARS = 8; + private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final List citedEntries = new ArrayList<>(); private int lastCitationNumber = 0; private boolean isNumericStyle = false; + private MarkManager markManager; + + public CSLCitationOOAdapter(XTextDocument doc) throws Exception { + this.markManager = new MarkManager(doc); + } public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws IllegalArgumentException, WrappedTargetException, CreationException { @@ -44,12 +50,11 @@ public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationSt isNumericStyle = checkIfNumericStyle(style); List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); - if (isNumericStyle) { - citations = updateCitationNumbers(citations, entries); - } - for (String citation : citations) { - writeCitation(doc, cursor, citation); + for (int i = 0; i < citations.size(); i++) { + BibEntry entry = entries.get(i); + String citation = citations.get(i); + insertCitation(doc, cursor, entry, citation); } } @@ -57,59 +62,41 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se throws IOException, WrappedTargetException, CreationException { String style = selectedStyle.getSource(); + isNumericStyle = checkIfNumericStyle(style); String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); - if (isNumericStyle) { - inTextCitation = updateCitationNumbers(List.of(inTextCitation), entries).getFirst(); - } - - writeCitation(doc, cursor, inTextCitation); - } - private List updateCitationNumbers(List citations, List entries) { - List updatedCitations = new ArrayList<>(); - for (int i = 0; i < citations.size(); i++) { - updatedCitations.add(updateSingleCitation(citations.get(i), entries)); + for (BibEntry entry : entries) { + insertCitation(doc, cursor, entry, inTextCitation); } - return updatedCitations; } - private String updateSingleCitation(String citation, List entries) { - Pattern pattern = Pattern.compile("(\\[?)(\\d+)(\\]?)(\\.)?(\\s*)"); - Matcher matcher = pattern.matcher(citation); - StringBuilder sb = new StringBuilder(); - - while (matcher.find()) { - try { - int index = Integer.parseInt(matcher.group(2)) - 1; - if (index >= 0 && index < entries.size()) { - BibEntry currentEntry = entries.get(index); - if (!citedEntries.contains(currentEntry)) { - lastCitationNumber++; - citedEntries.add(currentEntry); - } - int currentNumber = citedEntries.indexOf(currentEntry) + 1; - - String prefix = matcher.group(1); - String suffix = matcher.group(3); - String dot = matcher.group(4) != null ? "." : ""; - String space = matcher.group(5); - - String replacement = prefix + currentNumber + suffix + dot + space; - matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); - } else { - // If the index is out of bounds, append the original match - matcher.appendReplacement(sb, matcher.group()); - } - } catch (NumberFormatException e) { - // If parsing fails, append the original match - matcher.appendReplacement(sb, matcher.group()); - Logger.warn("Failed to parse citation number: " + matcher.group(2)); + private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry, String citation) throws WrappedTargetException, CreationException { + try { + ReferenceMark mark = markManager.createReferenceMark(entry, "ReferenceMark"); + + if (!citedEntries.contains(entry)) { + lastCitationNumber++; + citedEntries.add(entry); + } + int currentNumber = citedEntries.indexOf(entry) + 1; + + if (isNumericStyle) { + citation = updateCitationNumber(citation, currentNumber); } + + String formattedCitation = transformHtml(citation); + OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); + + mark.insertInText(doc, cursor, ooText); + cursor.collapseToEnd(); + } catch (Exception e) { + Logger.error("Error inserting citation", e); } - matcher.appendTail(sb); + } - return sb.toString(); + private String updateCitationNumber(String citation, int currentNumber) { + return citation.replaceFirst("\\d+", String.valueOf(currentNumber)); } private boolean checkIfNumericStyle(String styleXml) { @@ -130,48 +117,27 @@ private boolean checkIfNumericStyle(String styleXml) { } } - private void writeCitation(XTextDocument doc, XTextCursor cursor, String citation) throws WrappedTargetException, CreationException { - String formattedCitation = transformHtml(citation); - OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); - OOTextIntoOO.write(doc, cursor, ooText); - cursor.collapseToEnd(); - } - - /** - * Transforms provided HTML into a format that can be fully parsed by OOTextIntoOO.write(...) - * The transformed HTML can be used for inserting into a LibreOffice document - * Context: The HTML produced by CitationStyleGenerator.generateCitation(...) is not directly (completely) parsable by OOTextIntoOO.write(...) - * For more details, read the documentation of the write(...) method in the {@link OOTextIntoOO} class. - * Additional information: .... - * - * @param html The HTML string to be transformed into OO-write ready HTML. - */ private String transformHtml(String html) { - // Initial clean up of escaped characters html = StringEscapeUtils.unescapeHtml4(html); - - // Handle margins (spaces between citation number and text) html = html.replaceAll("
(.*?)
(.*?)
", "$1 $2"); - - // Remove unsupported tags html = html.replaceAll("]*>", ""); html = html.replace("", ""); - - // Remove unsupported links html = html.replaceAll("]*>", ""); html = html.replace("", ""); - - // Replace span tags with inline styles for bold html = html.replaceAll("(.*?)", "$1"); - - // Replace span tags with inline styles for italic html = html.replaceAll("(.*?)", "$1"); - html = html.replaceAll("(.*?)", "$1"); - - // Clean up any remaining span tags html = html.replaceAll("]*>", ""); - return html; } + + public static String getRandomString(int len) { + String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + Random rnd = new Random(); + StringBuilder sb = new StringBuilder(len); + for (int i = 0; i < len; i++) { + sb.append(chars.charAt(rnd.nextInt(chars.length()))); + } + return sb.toString(); + } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java new file mode 100644 index 00000000000..e1db793a23d --- /dev/null +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java @@ -0,0 +1,87 @@ +package org.jabref.logic.openoffice.oocsltext; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.IdentityHashMap; + +import org.jabref.model.entry.BibEntry; + +import com.sun.star.container.XNamed; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.text.XTextDocument; +import com.sun.star.uno.UnoRuntime; + +public class MarkManager { + private final HashMap marksByName; + private final ArrayList marksByID; + private final IdentityHashMap idsByMark; + private final XTextDocument document; + private final XMultiServiceFactory factory; + + public MarkManager(XTextDocument document) throws Exception { + this.document = document; + this.factory = UnoRuntime.queryInterface(XMultiServiceFactory.class, document); + this.marksByName = new HashMap<>(); + this.marksByID = new ArrayList<>(); + this.idsByMark = new IdentityHashMap<>(); + } + + public void renameMark(String oldName, String newName) { + ReferenceMark mark = marksByName.remove(oldName); + if (mark != null) { + marksByName.put(newName, mark); + } + } + + public int getIDForMark(ReferenceMark mark) { + return idsByMark.getOrDefault(mark, -1); + } + + public ReferenceMark getMarkForID(int id) { + return (id >= 0 && id < marksByID.size()) ? marksByID.get(id) : null; + } + + public ReferenceMark getMark(Object mark, String fieldType) { + if (mark == null) { + return null; + } + + XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); + String name = named.getName(); + + ReferenceMark referenceMark = marksByName.get(name); + if (referenceMark != null) { + return referenceMark; + } + + for (String prefix : CSLCitationOOAdapter.PREFIXES) { + if (name.contains(prefix)) { + try { + referenceMark = new ReferenceMark(document, named, name); + marksByName.put(name, referenceMark); + idsByMark.put(referenceMark, marksByID.size()); + marksByID.add(referenceMark); + return referenceMark; + } catch (IllegalArgumentException e) { + // Ignore and continue + } + } + } + + return null; + } + + public ReferenceMark createReferenceMark(BibEntry entry, String fieldType) throws Exception { + String name = CSLCitationOOAdapter.PREFIXES[0] + entry.getCitationKey().orElse("") + " RND" + CSLCitationOOAdapter.getRandomString(CSLCitationOOAdapter.REFMARK_ADD_CHARS); + Object mark = factory.createInstance("com.sun.star.text.ReferenceMark"); + XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); + named.setName(name); + + ReferenceMark referenceMark = new ReferenceMark(document, named, name); + marksByName.put(name, referenceMark); + idsByMark.put(referenceMark, marksByID.size()); + marksByID.add(referenceMark); + + return referenceMark; + } +} diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java new file mode 100644 index 00000000000..491e1b32b87 --- /dev/null +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java @@ -0,0 +1,43 @@ +package org.jabref.logic.openoffice.oocsltext; + +import org.jabref.model.openoffice.ootext.OOText; +import org.jabref.model.openoffice.ootext.OOTextIntoOO; +import org.jabref.model.openoffice.uno.CreationException; + +import com.sun.star.container.XNamed; +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.text.XTextContent; +import com.sun.star.text.XTextCursor; +import com.sun.star.text.XTextDocument; +import com.sun.star.uno.UnoRuntime; + +public class ReferenceMark { + private final XTextDocument document; + private final XNamed named; + private final String name; + private XTextContent textContent; + + public ReferenceMark(XTextDocument document, XNamed named, String name) { + this.document = document; + this.named = named; + this.name = name; + this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); + } + + public void insertInText(XTextDocument doc, XTextCursor cursor, OOText ooText) throws WrappedTargetException, CreationException { + // First, insert the text content (ReferenceMark) at the cursor position + cursor.getText().insertTextContent(cursor, textContent, true); + + // Then, insert the formatted text inside the ReferenceMark + XTextCursor markCursor = textContent.getAnchor().getText().createTextCursorByRange(textContent.getAnchor()); + OOTextIntoOO.write(doc, markCursor, ooText); + } + + public String getName() { + return name; + } + + public XTextContent getTextContent() { + return textContent; + } +} From bf9d39ed9f147092246b3d9ef50ee7f0c447ff52 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 13:59:32 +0530 Subject: [PATCH 03/94] Rehauled implementation --- .../org/jabref/gui/openoffice/OOBibBase.java | 37 +++---- .../oocsltext/CSLCitationOOAdapter.java | 96 +++++++---------- .../openoffice/oocsltext/MarkManager.java | 100 +++++++++++------- .../openoffice/oocsltext/ReferenceMark.java | 9 ++ 4 files changed, 126 insertions(+), 116 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 70fb6ca2cbe..9702b28588d 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -58,20 +58,14 @@ /** * Class for manipulating the Bibliography of the currently started document in OpenOffice. */ -class OOBibBase { +public class OOBibBase { private static final Logger LOGGER = LoggerFactory.getLogger(OOBibBase.class); private final DialogService dialogService; - - // After inserting a citation, if ooPrefs.getSyncWhenCiting() returns true, shall we also update the bibliography? private final boolean refreshBibliographyDuringSyncWhenCiting; - - // Shall we add "Cited on pages: ..." to resolved bibliography entries? private final boolean alwaysAddCitedOnPages; - private final OOBibBaseConnect connection; - private CSLCitationOOAdapter cslCitationOOAdapter; public OOBibBase(Path loPath, DialogService dialogService) @@ -81,29 +75,37 @@ public OOBibBase(Path loPath, DialogService dialogService) this.dialogService = dialogService; this.connection = new OOBibBaseConnect(loPath, dialogService); - this.refreshBibliographyDuringSyncWhenCiting = false; this.alwaysAddCitedOnPages = false; } + private void initializeCitationAdapter(XTextDocument doc) { + try { + this.cslCitationOOAdapter = new CSLCitationOOAdapter(doc); + this.cslCitationOOAdapter.readExistingMarks(); + } catch (Exception e) { + LOGGER.error("Error initializing CSLCitationOOAdapter", e); + } + } + public void guiActionSelectDocument(boolean autoSelectForSingle) { final String errorTitle = Localization.lang("Problem connecting"); try { - this.connection.selectDocument(autoSelectForSingle); } catch (NoDocumentFoundException ex) { OOError.from(ex).showErrorDialog(dialogService); } catch (DisposedException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); } catch (WrappedTargetException - | IndexOutOfBoundsException - | NoSuchElementException ex) { + | IndexOutOfBoundsException + | NoSuchElementException ex) { LOGGER.warn("Problem connecting", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } if (this.isConnectedToDocument()) { + initializeCitationAdapter(this.getXTextDocument().get()); dialogService.notify(Localization.lang("Connected to document") + ": " + this.getCurrentDocumentTitle().orElse("")); } @@ -565,9 +567,6 @@ public void guiActionInsertEntry(List entries, } } - /* - * For sync we need a FunctionalTextViewCursor. - */ OOResult fcursor = null; if (syncOptions.isPresent()) { fcursor = getFunctionalTextViewCursor(doc, errorTitle); @@ -591,14 +590,12 @@ public void guiActionInsertEntry(List entries, UnoUndo.enterUndoContext(doc, "Insert citation"); if (style instanceof CitationStyle citationStyle) { CSLCitationOOAdapter adapter = getOrCreateCSLCitationOOAdapter(doc); - // Handle insertion of CSL Style citations if (citationType == CitationType.AUTHORYEAR_INTEXT) { - cslCitationOOAdapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + adapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } else { - cslCitationOOAdapter.insertBibliography(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + adapter.insertBibliography(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } } else if (style instanceof JStyle jStyle) { - // Handle insertion of JStyle citations EditInsert.insertCitationGroup(doc, frontend.get(), cursor.get(), @@ -616,8 +613,7 @@ public void guiActionInsertEntry(List entries, OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); } catch (DisposedException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); - } catch ( - Exception ex) { + } catch (Exception ex) { LOGGER.warn("Could not insert entry", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } finally { @@ -877,6 +873,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) private CSLCitationOOAdapter getOrCreateCSLCitationOOAdapter(XTextDocument doc) throws Exception { if (cslCitationOOAdapter == null) { cslCitationOOAdapter = new CSLCitationOOAdapter(doc); + cslCitationOOAdapter.readExistingMarks(); } return cslCitationOOAdapter; } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 6db9666f8d6..d28e650afa8 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,13 +1,9 @@ package org.jabref.logic.openoffice.oocsltext; -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; import java.util.List; import java.util.Random; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; @@ -17,16 +13,10 @@ import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; -import org.jabref.model.openoffice.uno.CreationException; -import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import org.apache.commons.text.StringEscapeUtils; -import org.tinylog.Logger; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.InputSource; public class CSLCitationOOAdapter { @@ -34,20 +24,22 @@ public class CSLCitationOOAdapter { public static final int REFMARK_ADD_CHARS = 8; private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; - private final List citedEntries = new ArrayList<>(); - private int lastCitationNumber = 0; - private boolean isNumericStyle = false; + private final XTextDocument document; private MarkManager markManager; public CSLCitationOOAdapter(XTextDocument doc) throws Exception { + this.document = doc; this.markManager = new MarkManager(doc); } + public void readExistingMarks() throws Exception { + markManager.readExistingMarks(); + } + public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws IllegalArgumentException, WrappedTargetException, CreationException { + throws Exception { String style = selectedStyle.getSource(); - isNumericStyle = checkIfNumericStyle(style); List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); @@ -59,10 +51,9 @@ public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationSt } public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws IOException, WrappedTargetException, CreationException { + throws Exception { String style = selectedStyle.getSource(); - isNumericStyle = checkIfNumericStyle(style); String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); @@ -71,50 +62,41 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se } } - private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry, String citation) throws WrappedTargetException, CreationException { - try { - ReferenceMark mark = markManager.createReferenceMark(entry, "ReferenceMark"); + private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry, String citation) throws Exception { + String citationKey = entry.getCitationKey().orElse(""); + int currentNumber = markManager.getCitationNumber(citationKey); - if (!citedEntries.contains(entry)) { - lastCitationNumber++; - citedEntries.add(entry); - } - int currentNumber = citedEntries.indexOf(entry) + 1; - - if (isNumericStyle) { - citation = updateCitationNumber(citation, currentNumber); - } + ReferenceMark mark = markManager.createReferenceMark(entry, "ReferenceMark"); - String formattedCitation = transformHtml(citation); - OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); + String formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); + OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); - mark.insertInText(doc, cursor, ooText); - cursor.collapseToEnd(); - } catch (Exception e) { - Logger.error("Error inserting citation", e); - } - } - - private String updateCitationNumber(String citation, int currentNumber) { - return citation.replaceFirst("\\d+", String.valueOf(currentNumber)); + mark.insertInText(doc, cursor, ooText); + cursor.collapseToEnd(); } - private boolean checkIfNumericStyle(String styleXml) { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(new InputSource(new StringReader(styleXml))); - - Element styleElement = doc.getDocumentElement(); - Element infoElement = (Element) styleElement.getElementsByTagName("info").item(0); - Element categoryElement = (Element) infoElement.getElementsByTagName("category").item(0); - - String citationFormat = categoryElement.getAttribute("citation-format"); - return "numeric".equals(citationFormat); - } catch (Exception e) { - Logger.error("Error parsing CSL style XML", e); - return false; + private String updateSingleCitation(String citation, int currentNumber) { + Pattern pattern = Pattern.compile("(\\[?)(\\d+)(\\]?)(\\.)?(\\s*)"); + Matcher matcher = pattern.matcher(citation); + StringBuilder sb = new StringBuilder(); + boolean numberReplaced = false; + + while (matcher.find()) { + if (!numberReplaced) { + String prefix = matcher.group(1); + String suffix = matcher.group(3); + String dot = matcher.group(4) != null ? "." : ""; + String space = matcher.group(5); + String replacement = prefix + currentNumber + suffix + dot + space; + matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); + numberReplaced = true; + } else { + // If we've already replaced the number, keep any subsequent numbers as they are + matcher.appendReplacement(sb, matcher.group()); + } } + matcher.appendTail(sb); + return sb.toString(); } private String transformHtml(String html) { diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java index e1db793a23d..a16af95205c 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java @@ -6,8 +6,10 @@ import org.jabref.model.entry.BibEntry; +import com.sun.star.container.XNameAccess; import com.sun.star.container.XNamed; import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.text.XReferenceMarksSupplier; import com.sun.star.text.XTextDocument; import com.sun.star.uno.UnoRuntime; @@ -17,6 +19,9 @@ public class MarkManager { private final IdentityHashMap idsByMark; private final XTextDocument document; private final XMultiServiceFactory factory; + private int lastUsedCitationNumber = 0; + private HashMap citationKeyToNumber; // Add this line + private int highestCitationNumber = 0; public MarkManager(XTextDocument document) throws Exception { this.document = document; @@ -24,64 +29,81 @@ public MarkManager(XTextDocument document) throws Exception { this.marksByName = new HashMap<>(); this.marksByID = new ArrayList<>(); this.idsByMark = new IdentityHashMap<>(); + this.citationKeyToNumber = new HashMap<>(); } - public void renameMark(String oldName, String newName) { - ReferenceMark mark = marksByName.remove(oldName); - if (mark != null) { - marksByName.put(newName, mark); + public void readExistingMarks() throws Exception { + XReferenceMarksSupplier supplier = UnoRuntime.queryInterface(XReferenceMarksSupplier.class, document); + XNameAccess marks = supplier.getReferenceMarks(); + for (String name : marks.getElementNames()) { + if (name.startsWith(CSLCitationOOAdapter.PREFIXES[0])) { + XNamed named = UnoRuntime.queryInterface(XNamed.class, marks.getByName(name)); + ReferenceMark mark = new ReferenceMark(document, named, name); + addMark(mark); + } } } - public int getIDForMark(ReferenceMark mark) { - return idsByMark.getOrDefault(mark, -1); - } - - public ReferenceMark getMarkForID(int id) { - return (id >= 0 && id < marksByID.size()) ? marksByID.get(id) : null; + public void addMark(ReferenceMark mark) { + marksByName.put(mark.getName(), mark); + idsByMark.put(mark, marksByID.size()); + marksByID.add(mark); + updateCitationInfo(mark.getName()); } - public ReferenceMark getMark(Object mark, String fieldType) { - if (mark == null) { - return null; - } - - XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); - String name = named.getName(); - - ReferenceMark referenceMark = marksByName.get(name); - if (referenceMark != null) { - return referenceMark; - } - - for (String prefix : CSLCitationOOAdapter.PREFIXES) { - if (name.contains(prefix)) { - try { - referenceMark = new ReferenceMark(document, named, name); - marksByName.put(name, referenceMark); - idsByMark.put(referenceMark, marksByID.size()); - marksByID.add(referenceMark); - return referenceMark; - } catch (IllegalArgumentException e) { - // Ignore and continue - } + private void updateCitationInfo(String name) { + String[] parts = name.split(" "); + if (parts.length >= 3) { + String citationKey = parts[1]; + try { + int citationNumber = Integer.parseInt(parts[parts.length - 1]); + citationKeyToNumber.put(citationKey, citationNumber); + highestCitationNumber = Math.max(highestCitationNumber, citationNumber); + } catch (NumberFormatException e) { + // Ignore if we can't parse the number } } + } - return null; + public int getCitationNumber(String citationKey) { + return citationKeyToNumber.computeIfAbsent(citationKey, k -> { + highestCitationNumber++; + return highestCitationNumber; + }); } public ReferenceMark createReferenceMark(BibEntry entry, String fieldType) throws Exception { - String name = CSLCitationOOAdapter.PREFIXES[0] + entry.getCitationKey().orElse("") + " RND" + CSLCitationOOAdapter.getRandomString(CSLCitationOOAdapter.REFMARK_ADD_CHARS); + String citationKey = entry.getCitationKey().orElse(""); + int citationNumber = getCitationNumber(citationKey); + + String name = CSLCitationOOAdapter.PREFIXES[0] + citationKey + " RND" + citationNumber; Object mark = factory.createInstance("com.sun.star.text.ReferenceMark"); XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); named.setName(name); ReferenceMark referenceMark = new ReferenceMark(document, named, name); - marksByName.put(name, referenceMark); - idsByMark.put(referenceMark, marksByID.size()); - marksByID.add(referenceMark); + addMark(referenceMark); return referenceMark; } + + public int getHighestCitationNumber() { + return highestCitationNumber; + } + + public void setHighestCitationNumber(int number) { + this.highestCitationNumber = number; + } + + public ReferenceMark getMarkByName(String name) { + return marksByName.get(name); + } + + public ReferenceMark getMarkByID(int id) { + return marksByID.get(id); + } + + public int getIDForMark(ReferenceMark mark) { + return idsByMark.get(mark); + } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java index 491e1b32b87..a031b6d2bc0 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java @@ -16,12 +16,17 @@ public class ReferenceMark { private final XNamed named; private final String name; private XTextContent textContent; + private String citationKey; public ReferenceMark(XTextDocument document, XNamed named, String name) { this.document = document; this.named = named; this.name = name; this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); + String[] parts = name.split(" "); + if (parts.length >= 2) { + this.citationKey = parts[1]; + } } public void insertInText(XTextDocument doc, XTextCursor cursor, OOText ooText) throws WrappedTargetException, CreationException { @@ -40,4 +45,8 @@ public String getName() { public XTextContent getTextContent() { return textContent; } + + public String getCitationKey() { + return citationKey; + } } From fa39637b6584b06ddb19cad78c26b0002873b997 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:03:10 +0530 Subject: [PATCH 04/94] Remove comment --- .../org/jabref/logic/openoffice/oocsltext/ReferenceMark.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java index a031b6d2bc0..9022e68392b 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java @@ -30,10 +30,8 @@ public ReferenceMark(XTextDocument document, XNamed named, String name) { } public void insertInText(XTextDocument doc, XTextCursor cursor, OOText ooText) throws WrappedTargetException, CreationException { - // First, insert the text content (ReferenceMark) at the cursor position - cursor.getText().insertTextContent(cursor, textContent, true); - // Then, insert the formatted text inside the ReferenceMark + cursor.getText().insertTextContent(cursor, textContent, true); XTextCursor markCursor = textContent.getAnchor().getText().createTextCursorByRange(textContent.getAnchor()); OOTextIntoOO.write(doc, markCursor, ooText); } From bb441b4d3b9515de91e01cd91c628e2e15ba89bc Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:12:31 +0530 Subject: [PATCH 05/94] Revert removals --- .../org/jabref/gui/openoffice/OOBibBase.java | 14 +++++++ .../oocsltext/CSLCitationOOAdapter.java | 40 +++++++++++++------ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 9702b28588d..e5997f2b8da 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -63,9 +63,15 @@ public class OOBibBase { private static final Logger LOGGER = LoggerFactory.getLogger(OOBibBase.class); private final DialogService dialogService; + + // After inserting a citation, if ooPrefs.getSyncWhenCiting() returns true, shall we also update the bibliography? private final boolean refreshBibliographyDuringSyncWhenCiting; + + // Shall we add "Cited on pages: ..." to resolved bibliography entries? private final boolean alwaysAddCitedOnPages; + private final OOBibBaseConnect connection; + private CSLCitationOOAdapter cslCitationOOAdapter; public OOBibBase(Path loPath, DialogService dialogService) @@ -75,6 +81,7 @@ public OOBibBase(Path loPath, DialogService dialogService) this.dialogService = dialogService; this.connection = new OOBibBaseConnect(loPath, dialogService); + this.refreshBibliographyDuringSyncWhenCiting = false; this.alwaysAddCitedOnPages = false; } @@ -92,6 +99,7 @@ public void guiActionSelectDocument(boolean autoSelectForSingle) { final String errorTitle = Localization.lang("Problem connecting"); try { + this.connection.selectDocument(autoSelectForSingle); } catch (NoDocumentFoundException ex) { OOError.from(ex).showErrorDialog(dialogService); @@ -567,6 +575,9 @@ public void guiActionInsertEntry(List entries, } } + /* + * For sync we need a FunctionalTextViewCursor. + */ OOResult fcursor = null; if (syncOptions.isPresent()) { fcursor = getFunctionalTextViewCursor(doc, errorTitle); @@ -587,8 +598,10 @@ public void guiActionInsertEntry(List entries, } try { + UnoUndo.enterUndoContext(doc, "Insert citation"); if (style instanceof CitationStyle citationStyle) { + // Handle insertion of CSL Style citations CSLCitationOOAdapter adapter = getOrCreateCSLCitationOOAdapter(doc); if (citationType == CitationType.AUTHORYEAR_INTEXT) { adapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); @@ -596,6 +609,7 @@ public void guiActionInsertEntry(List entries, adapter.insertBibliography(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } } else if (style instanceof JStyle jStyle) { + // Handle insertion of JStyle citations EditInsert.insertCitationGroup(doc, frontend.get(), cursor.get(), diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index d28e650afa8..1fde4ac94e7 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,7 +1,6 @@ package org.jabref.logic.openoffice.oocsltext; import java.util.List; -import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -13,7 +12,10 @@ import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; +import org.jabref.model.openoffice.ootext.OOTextIntoOO; +import org.jabref.model.openoffice.uno.CreationException; +import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import org.apache.commons.text.StringEscapeUtils; @@ -37,7 +39,7 @@ public void readExistingMarks() throws Exception { } public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws Exception { + throws IllegalArgumentException { String style = selectedStyle.getSource(); @@ -99,27 +101,41 @@ private String updateSingleCitation(String citation, int currentNumber) { return sb.toString(); } + /** + * Transforms provided HTML into a format that can be fully parsed by OOTextIntoOO.write(...) + * The transformed HTML can be used for inserting into a LibreOffice document + * Context: The HTML produced by CitationStyleGenerator.generateCitation(...) is not directly (completely) parsable by OOTextIntoOO.write(...) + * For more details, read the documentation of the write(...) method in the {@link OOTextIntoOO} class. + * Additional information: .... + * + * @param html The HTML string to be transformed into OO-write ready HTML. + */ private String transformHtml(String html) { + // Initial clean up of escaped characters html = StringEscapeUtils.unescapeHtml4(html); + + // Handle margins (spaces between citation number and text) html = html.replaceAll("
(.*?)
(.*?)
", "$1 $2"); + + // Remove unsupported tags html = html.replaceAll("]*>", ""); html = html.replace("", ""); + + // Remove unsupported links html = html.replaceAll("]*>", ""); html = html.replace("", ""); + + // Replace span tags with inline styles for bold html = html.replaceAll("(.*?)", "$1"); + + // Replace span tags with inline styles for italic html = html.replaceAll("(.*?)", "$1"); + html = html.replaceAll("(.*?)", "$1"); + + // Clean up any remaining span tags html = html.replaceAll("]*>", ""); - return html; - } - public static String getRandomString(int len) { - String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - Random rnd = new Random(); - StringBuilder sb = new StringBuilder(len); - for (int i = 0; i < len; i++) { - sb.append(chars.charAt(rnd.nextInt(chars.length()))); - } - return sb.toString(); + return html; } } From 649bcc6a5a8d64c4a978e44fe001b4c6d8e5873e Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:14:20 +0530 Subject: [PATCH 06/94] Revert removals --- .../jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 1fde4ac94e7..74bdd325245 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -39,7 +39,7 @@ public void readExistingMarks() throws Exception { } public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws IllegalArgumentException { + throws Exception { String style = selectedStyle.getSource(); From 9c47086dc2aed06a81964f6d67f02030a7bb87cf Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:14:44 +0530 Subject: [PATCH 07/94] Revert removals --- .../jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 74bdd325245..58c8f916e9c 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -13,9 +13,7 @@ import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; -import org.jabref.model.openoffice.uno.CreationException; -import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import org.apache.commons.text.StringEscapeUtils; From 929cf1d65c879b63ebc721a1f0a39eaae6c66270 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:24:21 +0530 Subject: [PATCH 08/94] Cover edge cases of numeric citation types --- .../oocsltext/CSLCitationOOAdapter.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 58c8f916e9c..23cbe47f519 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -76,18 +76,26 @@ private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entr } private String updateSingleCitation(String citation, int currentNumber) { - Pattern pattern = Pattern.compile("(\\[?)(\\d+)(\\]?)(\\.)?(\\s*)"); + // This pattern now accounts for [1], (1), 1., and 1 + Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); Matcher matcher = pattern.matcher(citation); StringBuilder sb = new StringBuilder(); boolean numberReplaced = false; while (matcher.find()) { if (!numberReplaced) { - String prefix = matcher.group(1); - String suffix = matcher.group(3); + String prefix = matcher.group(1) != null ? matcher.group(1) : ""; + String suffix = matcher.group(3) != null ? matcher.group(3) : ""; String dot = matcher.group(4) != null ? "." : ""; - String space = matcher.group(5); - String replacement = prefix + currentNumber + suffix + dot + space; + + // Ensure we maintain the original format (brackets, parentheses, or neither) + String replacement; + if (prefix.isEmpty() && suffix.isEmpty()) { + replacement = currentNumber + dot + " "; + } else { + replacement = prefix + currentNumber + suffix + dot + " "; + } + matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); numberReplaced = true; } else { From 89211c3e992911ef6c0d472e31132bf8c62975bf Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:25:10 +0530 Subject: [PATCH 09/94] Cover edge cases of numeric citation types --- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 23cbe47f519..a0c227b9be0 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -76,7 +76,7 @@ private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entr } private String updateSingleCitation(String citation, int currentNumber) { - // This pattern now accounts for [1], (1), 1., and 1 + Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); Matcher matcher = pattern.matcher(citation); StringBuilder sb = new StringBuilder(); @@ -88,7 +88,6 @@ private String updateSingleCitation(String citation, int currentNumber) { String suffix = matcher.group(3) != null ? matcher.group(3) : ""; String dot = matcher.group(4) != null ? "." : ""; - // Ensure we maintain the original format (brackets, parentheses, or neither) String replacement; if (prefix.isEmpty() && suffix.isEmpty()) { replacement = currentNumber + dot + " "; From 1e4d5a97e214e006dc1aea0e902022c1d74d3b30 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:45:48 +0530 Subject: [PATCH 10/94] Better handling of numeric styles --- .../oocsltext/CSLCitationOOAdapter.java | 86 +++++++++++++------ 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index a0c227b9be0..325f3f19a41 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,9 +1,13 @@ package org.jabref.logic.openoffice.oocsltext; +import java.io.StringReader; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; import org.jabref.logic.citationstyle.CitationStyleOutputFormat; @@ -17,6 +21,10 @@ import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import org.apache.commons.text.StringEscapeUtils; +import org.tinylog.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; public class CSLCitationOOAdapter { @@ -26,6 +34,7 @@ public class CSLCitationOOAdapter { private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; private MarkManager markManager; + private boolean isNumericStyle = false; public CSLCitationOOAdapter(XTextDocument doc) throws Exception { this.document = doc; @@ -40,6 +49,7 @@ public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationSt throws Exception { String style = selectedStyle.getSource(); + isNumericStyle = checkIfNumericStyle(style); List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); @@ -54,6 +64,7 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se throws Exception { String style = selectedStyle.getSource(); + isNumericStyle = checkIfNumericStyle(style); String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); @@ -67,43 +78,64 @@ private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entr int currentNumber = markManager.getCitationNumber(citationKey); ReferenceMark mark = markManager.createReferenceMark(entry, "ReferenceMark"); - - String formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); + String formattedCitation; + if (isNumericStyle) { + formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); + } else { + formattedCitation = transformHtml(citation); + } OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); mark.insertInText(doc, cursor, ooText); cursor.collapseToEnd(); } - private String updateSingleCitation(String citation, int currentNumber) { - - Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); - Matcher matcher = pattern.matcher(citation); - StringBuilder sb = new StringBuilder(); - boolean numberReplaced = false; - - while (matcher.find()) { - if (!numberReplaced) { - String prefix = matcher.group(1) != null ? matcher.group(1) : ""; - String suffix = matcher.group(3) != null ? matcher.group(3) : ""; - String dot = matcher.group(4) != null ? "." : ""; + private boolean checkIfNumericStyle(String styleXml) { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(styleXml))); + + Element styleElement = doc.getDocumentElement(); + Element infoElement = (Element) styleElement.getElementsByTagName("info").item(0); + Element categoryElement = (Element) infoElement.getElementsByTagName("category").item(0); + + String citationFormat = categoryElement.getAttribute("citation-format"); + return "numeric".equals(citationFormat); + } catch (Exception e) { + Logger.error("Error parsing CSL style XML", e); + return false; + } + } - String replacement; - if (prefix.isEmpty() && suffix.isEmpty()) { - replacement = currentNumber + dot + " "; + private String updateSingleCitation(String citation, int currentNumber) { + Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); + Matcher matcher = pattern.matcher(citation); + StringBuilder sb = new StringBuilder(); + boolean numberReplaced = false; + + while (matcher.find()) { + if (!numberReplaced) { + String prefix = matcher.group(1) != null ? matcher.group(1) : ""; + String suffix = matcher.group(3) != null ? matcher.group(3) : ""; + String dot = matcher.group(4) != null ? "." : ""; + + String replacement; + if (prefix.isEmpty() && suffix.isEmpty()) { + replacement = currentNumber + dot + " "; + } else { + replacement = prefix + currentNumber + suffix + dot + " "; + } + + matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); + numberReplaced = true; } else { - replacement = prefix + currentNumber + suffix + dot + " "; + // If we've already replaced the number, keep any subsequent numbers as they are + matcher.appendReplacement(sb, matcher.group()); } - - matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); - numberReplaced = true; - } else { - // If we've already replaced the number, keep any subsequent numbers as they are - matcher.appendReplacement(sb, matcher.group()); } - } - matcher.appendTail(sb); - return sb.toString(); + matcher.appendTail(sb); + return sb.toString(); } /** From 10bf9e06a7d82ad37e624d0e91a02a2523d2593f Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 14:48:55 +0530 Subject: [PATCH 11/94] Format doc --- .../oocsltext/CSLCitationOOAdapter.java | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 325f3f19a41..272316a4dcc 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -102,40 +102,41 @@ private boolean checkIfNumericStyle(String styleXml) { String citationFormat = categoryElement.getAttribute("citation-format"); return "numeric".equals(citationFormat); - } catch (Exception e) { + } catch ( + Exception e) { Logger.error("Error parsing CSL style XML", e); return false; } } private String updateSingleCitation(String citation, int currentNumber) { - Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); - Matcher matcher = pattern.matcher(citation); - StringBuilder sb = new StringBuilder(); - boolean numberReplaced = false; - - while (matcher.find()) { - if (!numberReplaced) { - String prefix = matcher.group(1) != null ? matcher.group(1) : ""; - String suffix = matcher.group(3) != null ? matcher.group(3) : ""; - String dot = matcher.group(4) != null ? "." : ""; - - String replacement; - if (prefix.isEmpty() && suffix.isEmpty()) { - replacement = currentNumber + dot + " "; - } else { - replacement = prefix + currentNumber + suffix + dot + " "; - } - - matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); - numberReplaced = true; + Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); + Matcher matcher = pattern.matcher(citation); + StringBuilder sb = new StringBuilder(); + boolean numberReplaced = false; + + while (matcher.find()) { + if (!numberReplaced) { + String prefix = matcher.group(1) != null ? matcher.group(1) : ""; + String suffix = matcher.group(3) != null ? matcher.group(3) : ""; + String dot = matcher.group(4) != null ? "." : ""; + + String replacement; + if (prefix.isEmpty() && suffix.isEmpty()) { + replacement = currentNumber + dot + " "; } else { - // If we've already replaced the number, keep any subsequent numbers as they are - matcher.appendReplacement(sb, matcher.group()); + replacement = prefix + currentNumber + suffix + dot + " "; } + + matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); + numberReplaced = true; + } else { + // If we've already replaced the number, keep any subsequent numbers as they are + matcher.appendReplacement(sb, matcher.group()); } - matcher.appendTail(sb); - return sb.toString(); + } + matcher.appendTail(sb); + return sb.toString(); } /** From 3d6c31392c8b8668d6a89d8b5536210453312232 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 16:03:32 +0530 Subject: [PATCH 12/94] Move isNumericStyle method to CitationStyle core --- .../logic/citationstyle/CitationStyle.java | 20 +++++++++++ .../oocsltext/CSLCitationOOAdapter.java | 33 +++---------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index efd3d78153e..d6892c68518 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -17,6 +17,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -237,4 +238,23 @@ public boolean isInternalStyle() { public String getPath() { return getFilePath(); } + + public boolean isNumericStyle() { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(source))); + + Element styleElement = doc.getDocumentElement(); + Element infoElement = (Element) styleElement.getElementsByTagName("info").item(0); + Element categoryElement = (Element) infoElement.getElementsByTagName("category").item(0); + + String citationFormat = categoryElement.getAttribute("citation-format"); + return "numeric".equals(citationFormat); + } catch ( + Exception e) { + org.tinylog.Logger.error("Error parsing CSL style XML", e); + return false; + } + } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 272316a4dcc..38047f70588 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,13 +1,9 @@ package org.jabref.logic.openoffice.oocsltext; -import java.io.StringReader; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; import org.jabref.logic.citationstyle.CitationStyleOutputFormat; @@ -21,10 +17,6 @@ import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import org.apache.commons.text.StringEscapeUtils; -import org.tinylog.Logger; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.InputSource; public class CSLCitationOOAdapter { @@ -49,7 +41,9 @@ public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationSt throws Exception { String style = selectedStyle.getSource(); - isNumericStyle = checkIfNumericStyle(style); + isNumericStyle = selectedStyle.isNumericStyle(); + + // TODO: constructor injection for style List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); @@ -64,7 +58,7 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se throws Exception { String style = selectedStyle.getSource(); - isNumericStyle = checkIfNumericStyle(style); + isNumericStyle = selectedStyle.isNumericStyle(); String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); @@ -90,25 +84,6 @@ private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entr cursor.collapseToEnd(); } - private boolean checkIfNumericStyle(String styleXml) { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(new InputSource(new StringReader(styleXml))); - - Element styleElement = doc.getDocumentElement(); - Element infoElement = (Element) styleElement.getElementsByTagName("info").item(0); - Element categoryElement = (Element) infoElement.getElementsByTagName("category").item(0); - - String citationFormat = categoryElement.getAttribute("citation-format"); - return "numeric".equals(citationFormat); - } catch ( - Exception e) { - Logger.error("Error parsing CSL style XML", e); - return false; - } - } - private String updateSingleCitation(String citation, int currentNumber) { Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); Matcher matcher = pattern.matcher(citation); From 2a24cfc47208d8cea8637f576acb99fcb2332c83 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 16:12:32 +0530 Subject: [PATCH 13/94] Log --- .../org/jabref/logic/openoffice/oocsltext/MarkManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java index a16af95205c..c5ee3273b69 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java @@ -12,6 +12,7 @@ import com.sun.star.text.XReferenceMarksSupplier; import com.sun.star.text.XTextDocument; import com.sun.star.uno.UnoRuntime; +import org.tinylog.Logger; public class MarkManager { private final HashMap marksByName; @@ -20,7 +21,7 @@ public class MarkManager { private final XTextDocument document; private final XMultiServiceFactory factory; private int lastUsedCitationNumber = 0; - private HashMap citationKeyToNumber; // Add this line + private HashMap citationKeyToNumber; private int highestCitationNumber = 0; public MarkManager(XTextDocument document) throws Exception { @@ -60,6 +61,7 @@ private void updateCitationInfo(String name) { citationKeyToNumber.put(citationKey, citationNumber); highestCitationNumber = Math.max(highestCitationNumber, citationNumber); } catch (NumberFormatException e) { + Logger.warn("WHat", e); // Ignore if we can't parse the number } } From 1475130f7a55a713af40dbffa477ff0a60fcb95d Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 19:54:48 +0530 Subject: [PATCH 14/94] Gosh, this finally works. --- .../org/jabref/gui/openoffice/OOBibBase.java | 11 ++++ .../oocsltext/CSLCitationOOAdapter.java | 3 ++ .../openoffice/oocsltext/MarkManager.java | 51 +++++-------------- .../openoffice/oocsltext/ReferenceMark.java | 20 +++++--- 4 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index e5997f2b8da..3e146c9e44c 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -117,6 +117,17 @@ public void guiActionSelectDocument(boolean autoSelectForSingle) { dialogService.notify(Localization.lang("Connected to document") + ": " + this.getCurrentDocumentTitle().orElse("")); } + + if (this.isConnectedToDocument()) { + try { + this.cslCitationOOAdapter = new CSLCitationOOAdapter(this.getXTextDocument().get()); + this.cslCitationOOAdapter.readExistingMarks(); + } catch (Exception e) { + LOGGER.error("Error initializing CSLCitationOOAdapter", e); + } + dialogService.notify(Localization.lang("Connected to document") + ": " + + this.getCurrentDocumentTitle().orElse("")); + } } /** diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 38047f70588..001a7ab5589 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -80,7 +80,10 @@ private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entr } OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); + // Insert the citation text wrapped in a reference mark mark.insertInText(doc, cursor, ooText); + + // Move the cursor to the end of the inserted text cursor.collapseToEnd(); } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java index c5ee3273b69..64c83b8d8ec 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.IdentityHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.jabref.model.entry.BibEntry; @@ -12,7 +14,6 @@ import com.sun.star.text.XReferenceMarksSupplier; import com.sun.star.text.XTextDocument; import com.sun.star.uno.UnoRuntime; -import org.tinylog.Logger; public class MarkManager { private final HashMap marksByName; @@ -20,7 +21,6 @@ public class MarkManager { private final IdentityHashMap idsByMark; private final XTextDocument document; private final XMultiServiceFactory factory; - private int lastUsedCitationNumber = 0; private HashMap citationKeyToNumber; private int highestCitationNumber = 0; @@ -41,10 +41,22 @@ public void readExistingMarks() throws Exception { XNamed named = UnoRuntime.queryInterface(XNamed.class, marks.getByName(name)); ReferenceMark mark = new ReferenceMark(document, named, name); addMark(mark); + updateCitationInfo(name); } } } + private void updateCitationInfo(String name) { + Pattern pattern = Pattern.compile("JABREF_(.+) RND(\\d+)"); // Format: JABREF_{citationKey} RND{citationNumber} + Matcher matcher = pattern.matcher(name); + if (matcher.find()) { + String citationKey = matcher.group(1); + int citationNumber = Integer.parseInt(matcher.group(2)); + citationKeyToNumber.put(citationKey, citationNumber); + highestCitationNumber = Math.max(highestCitationNumber, citationNumber); + } + } + public void addMark(ReferenceMark mark) { marksByName.put(mark.getName(), mark); idsByMark.put(mark, marksByID.size()); @@ -52,21 +64,6 @@ public void addMark(ReferenceMark mark) { updateCitationInfo(mark.getName()); } - private void updateCitationInfo(String name) { - String[] parts = name.split(" "); - if (parts.length >= 3) { - String citationKey = parts[1]; - try { - int citationNumber = Integer.parseInt(parts[parts.length - 1]); - citationKeyToNumber.put(citationKey, citationNumber); - highestCitationNumber = Math.max(highestCitationNumber, citationNumber); - } catch (NumberFormatException e) { - Logger.warn("WHat", e); - // Ignore if we can't parse the number - } - } - } - public int getCitationNumber(String citationKey) { return citationKeyToNumber.computeIfAbsent(citationKey, k -> { highestCitationNumber++; @@ -88,24 +85,4 @@ public ReferenceMark createReferenceMark(BibEntry entry, String fieldType) throw return referenceMark; } - - public int getHighestCitationNumber() { - return highestCitationNumber; - } - - public void setHighestCitationNumber(int number) { - this.highestCitationNumber = number; - } - - public ReferenceMark getMarkByName(String name) { - return marksByName.get(name); - } - - public ReferenceMark getMarkByID(int id) { - return marksByID.get(id); - } - - public int getIDForMark(ReferenceMark mark) { - return idsByMark.get(mark); - } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java index 9022e68392b..e1a2272126a 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java @@ -2,13 +2,12 @@ import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; -import org.jabref.model.openoffice.uno.CreationException; import com.sun.star.container.XNamed; -import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextContent; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; +import com.sun.star.text.XTextRange; import com.sun.star.uno.UnoRuntime; public class ReferenceMark { @@ -29,11 +28,20 @@ public ReferenceMark(XTextDocument document, XNamed named, String name) { } } - public void insertInText(XTextDocument doc, XTextCursor cursor, OOText ooText) throws WrappedTargetException, CreationException { + public void insertInText(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception { + // To debug: mark doesn't wrap around text!?? - cursor.getText().insertTextContent(cursor, textContent, true); - XTextCursor markCursor = textContent.getAnchor().getText().createTextCursorByRange(textContent.getAnchor()); - OOTextIntoOO.write(doc, markCursor, ooText); + // Insert the text content at the cursor position + OOTextIntoOO.write(doc, cursor, ooText); + + // Create a text range covering the just-inserted text + XTextRange start = cursor.getStart(); + XTextRange end = cursor.getEnd(); + cursor.gotoRange(start, false); + cursor.gotoRange(end, true); + + // Attach the reference mark to this range + textContent.attach(cursor); } public String getName() { From c9fe7a2cce5583d9c9a0a458f38d4af1a1cb80e7 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 21:01:51 +0530 Subject: [PATCH 15/94] First Implementation - Make bibliography --- .../org/jabref/gui/openoffice/OOBibBase.java | 94 ++++++++++++++++++- .../gui/openoffice/OpenOfficePanel.java | 2 +- .../oocsltext/CSLCitationOOAdapter.java | 5 + .../openoffice/oocsltext/MarkManager.java | 4 + 4 files changed, 99 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 3e146c9e44c..77a61427de1 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -46,12 +46,15 @@ import com.sun.star.beans.IllegalTypeException; import com.sun.star.beans.NotRemoveableException; import com.sun.star.beans.PropertyVetoException; +import com.sun.star.beans.XPropertySet; import com.sun.star.comp.helper.BootstrapException; import com.sun.star.container.NoSuchElementException; import com.sun.star.lang.DisposedException; import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; +import com.sun.star.text.XTextRange; +import com.sun.star.uno.UnoRuntime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -882,16 +885,97 @@ public void guiActionUpdateDocument(List databases, OOStyle style) unresolvedKeys.getFirst()); dialogService.showErrorDialogAndWait(errorTitle, msg); } - } catch (NoDocumentException ex) { + } catch ( + NoDocumentException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); - } catch (DisposedException ex) { + } catch ( + DisposedException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); - } catch (CreationException - | WrappedTargetException - | com.sun.star.lang.IllegalArgumentException ex) { + } catch ( + CreationException + | + WrappedTargetException + | + com.sun.star.lang.IllegalArgumentException ex) { LOGGER.warn("Could not update bibliography", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } + } else if (style instanceof CitationStyle citationStyle) { + final String errorTitle = Localization.lang("Unable to synchronize bibliography"); + + try { + OOResult odoc = getXTextDocument(); + if (testDialog(errorTitle, odoc.asVoidResult())) { + return; + } + + XTextDocument doc = odoc.get(); + + OOResult fcursor = getFunctionalTextViewCursor(doc, errorTitle); + + if (testDialog(errorTitle, + fcursor.asVoidResult(), + checkIfOpenOfficeIsRecordingChanges(doc))) { + return; + } + + try { + UnoUndo.enterUndoContext(doc, "Create CSL bibliography"); + + CSLCitationOOAdapter adapter = new CSLCitationOOAdapter(doc); + adapter.readExistingMarks(); + + // Collect only cited entries from all databases + List citedEntries = new ArrayList<>(); + for (BibDatabase database : databases) { + for (BibEntry entry : database.getEntries()) { + if (adapter.isCitedEntry(entry)) { + citedEntries.add(entry); + } + } + } + + // If no entries are cited, show a message and return + if (citedEntries.isEmpty()) { + dialogService.showInformationDialogAndWait( + Localization.lang("Bibliography"), + Localization.lang("No cited entries found in the document.") + ); + return; + } + + // Create a new cursor at the end of the document for bibliography insertion + XTextCursor bibliographyCursor = doc.getText().createTextCursor(); + bibliographyCursor.gotoEnd(false); + + // Insert bibliography title + String bibliographyTitle = Localization.lang("Bibliography"); + bibliographyCursor.setString(bibliographyTitle + "\n"); + + // Apply formatting to the title (e.g., make it bold and larger) + XTextRange titleRange = bibliographyCursor.getStart(); + titleRange.setString(bibliographyTitle); + XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); + titleProps.setPropertyValue("CharWeight", com.sun.star.awt.FontWeight.BOLD); + titleProps.setPropertyValue("CharHeight", 16f); // Adjust the size as needed + + // Move cursor to the next line for bibliography entries + bibliographyCursor.goRight((short) 1, false); + + // Insert bibliography entries + BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(databases.get(0)); // Assuming the first database is the main one + BibEntryTypesManager bibEntryTypesManager = new BibEntryTypesManager(); // You might need to inject this + + adapter.insertBibliography(doc, bibliographyCursor, citationStyle, citedEntries, bibDatabaseContext, bibEntryTypesManager); + } finally { + UnoUndo.leaveUndoContext(doc); + fcursor.get().restore(doc); + } + } catch ( + Exception ex) { + LOGGER.warn("Could not create bibliography", ex); + OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); + } } } diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index 5b8afe0aebf..624559b8a0d 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -229,7 +229,7 @@ private void initPanel() { pushEntriesAdvanced.setOnAction(e -> pushEntries(CitationType.AUTHORYEAR_INTEXT, true)); pushEntriesAdvanced.setMaxWidth(Double.MAX_VALUE); - update.setTooltip(new Tooltip(Localization.lang("Ensure that the bibliography is up-to-date"))); + update.setTooltip(new Tooltip(Localization.lang("Make or update the bibliography"))); update.setOnAction(event -> { String title = Localization.lang("Could not update bibliography"); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 001a7ab5589..118411884fb 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -154,4 +154,9 @@ private String transformHtml(String html) { return html; } + + public boolean isCitedEntry(BibEntry entry) { + String citationKey = entry.getCitationKey().orElse(""); + return markManager.hasCitationForKey(citationKey); + } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java index 64c83b8d8ec..854521f51b0 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java @@ -85,4 +85,8 @@ public ReferenceMark createReferenceMark(BibEntry entry, String fieldType) throw return referenceMark; } + + public boolean hasCitationForKey(String citationKey) { + return citationKeyToNumber.containsKey(citationKey); + } } From 6643bfd3c0c05386e7f5e4e029289b88a8c1dfa6 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 21:49:11 +0530 Subject: [PATCH 16/94] Better implementation --- .../gui/openoffice/OpenOfficePanel.java | 7 ++- .../oocsltext/CSLCitationOOAdapter.java | 5 +- .../openoffice/oocsltext/MarkManager.java | 52 ++++++++++++++++++- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index 624559b8a0d..6695cdb76a5 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -121,6 +121,7 @@ public OpenOfficePanel(LibraryTabContainer tabContainer, this.stateManager = stateManager; this.clipBoardManager = clipBoardManager; this.undoManager = undoManager; + this.currentStyle = preferencesService.getOpenOfficePreferences().getCurrentStyle(); ActionFactory factory = new ActionFactory(); @@ -229,7 +230,11 @@ private void initPanel() { pushEntriesAdvanced.setOnAction(e -> pushEntries(CitationType.AUTHORYEAR_INTEXT, true)); pushEntriesAdvanced.setMaxWidth(Double.MAX_VALUE); - update.setTooltip(new Tooltip(Localization.lang("Make or update the bibliography"))); + if (currentStyle instanceof CitationStyle) { + update.setTooltip(new Tooltip(Localization.lang("Make bibliography"))); + } else if (currentStyle instanceof JStyle) { + update.setTooltip(new Tooltip(Localization.lang("Make or update the bibliography"))); + } update.setOnAction(event -> { String title = Localization.lang("Could not update bibliography"); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 118411884fb..bc9f0e24974 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,5 +1,6 @@ package org.jabref.logic.openoffice.oocsltext; +import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -43,7 +44,8 @@ public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationSt String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); - // TODO: constructor injection for style + // Sort entries based on their order of appearance in the document + entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); @@ -60,6 +62,7 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); + entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); for (BibEntry entry : entries) { diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java index 854521f51b0..377bfeba496 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.IdentityHashMap; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -23,6 +24,8 @@ public class MarkManager { private final XMultiServiceFactory factory; private HashMap citationKeyToNumber; private int highestCitationNumber = 0; + private Map citationOrder = new HashMap<>(); + private int citationCounter = 0; public MarkManager(XTextDocument document) throws Exception { this.document = document; @@ -36,16 +39,61 @@ public MarkManager(XTextDocument document) throws Exception { public void readExistingMarks() throws Exception { XReferenceMarksSupplier supplier = UnoRuntime.queryInterface(XReferenceMarksSupplier.class, document); XNameAccess marks = supplier.getReferenceMarks(); + + citationOrder.clear(); + citationCounter = 0; + for (String name : marks.getElementNames()) { - if (name.startsWith(CSLCitationOOAdapter.PREFIXES[0])) { + String citationKey = extractCitationKey(name); + if (!citationKey.isEmpty()) { + citationOrder.putIfAbsent(citationKey, ++citationCounter); + XNamed named = UnoRuntime.queryInterface(XNamed.class, marks.getByName(name)); ReferenceMark mark = new ReferenceMark(document, named, name); addMark(mark); - updateCitationInfo(name); } } } + /** + * Extracts the citation key from a reference mark name. + * + * @param name The name of the reference mark + * @return The extracted citation key, or an empty string if no key could be extracted + */ + private String extractCitationKey(String name) { + // Check if the name starts with one of the known prefixes + for (String prefix : CSLCitationOOAdapter.PREFIXES) { + if (name.startsWith(prefix)) { + // Remove the prefix + String withoutPrefix = name.substring(prefix.length()); + + // Split the remaining string by space + String[] parts = withoutPrefix.split("\\s+"); + + if (parts.length > 0) { + // The first part should be the citation key + String key = parts[0]; + + // Remove any non-alphanumeric characters from the start and end + key = key.replaceAll("^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$", ""); + + // If we have a non-empty key, return it + if (!key.isEmpty()) { + return key; + } + } + + // If we couldn't extract a key after removing the prefix, + // no need to check other prefixes + break; + } + } + + // If no key could be extracted, return an empty string + return ""; + } + private void updateCitationInfo(String name) { Pattern pattern = Pattern.compile("JABREF_(.+) RND(\\d+)"); // Format: JABREF_{citationKey} RND{citationNumber} Matcher matcher = pattern.matcher(name); From 05a50fcc728e52b8e329d9e8356a6c1b85135b9c Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 3 Aug 2024 22:36:57 +0530 Subject: [PATCH 17/94] Remove duplicate notification --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 3e146c9e44c..36f7ecb115f 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -116,17 +116,12 @@ public void guiActionSelectDocument(boolean autoSelectForSingle) { initializeCitationAdapter(this.getXTextDocument().get()); dialogService.notify(Localization.lang("Connected to document") + ": " + this.getCurrentDocumentTitle().orElse("")); - } - - if (this.isConnectedToDocument()) { try { this.cslCitationOOAdapter = new CSLCitationOOAdapter(this.getXTextDocument().get()); this.cslCitationOOAdapter.readExistingMarks(); } catch (Exception e) { LOGGER.error("Error initializing CSLCitationOOAdapter", e); } - dialogService.notify(Localization.lang("Connected to document") + ": " - + this.getCurrentDocumentTitle().orElse("")); } } From c1f5c6a552d53b0ce1cfb915e980760d0508bbb2 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 01:24:46 +0530 Subject: [PATCH 18/94] Penultimate - finishing reference section, fix formatting --- .../org/jabref/gui/openoffice/OOBibBase.java | 40 ++++++++----------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 77a61427de1..e3bbd3893da 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -43,6 +43,7 @@ import org.jabref.model.openoffice.util.OOResult; import org.jabref.model.openoffice.util.OOVoidResult; +import com.airhacks.afterburner.injection.Injector; import com.sun.star.beans.IllegalTypeException; import com.sun.star.beans.NotRemoveableException; import com.sun.star.beans.PropertyVetoException; @@ -835,9 +836,8 @@ public Optional exportCitedHelper(List databases, bool * @param style Style. */ public void guiActionUpdateDocument(List databases, OOStyle style) { + final String errorTitle = Localization.lang("Unable to synchronize bibliography"); if (style instanceof JStyle jStyle) { - final String errorTitle = Localization.lang("Unable to synchronize bibliography"); - try { OOResult odoc = getXTextDocument(); @@ -885,24 +885,17 @@ public void guiActionUpdateDocument(List databases, OOStyle style) unresolvedKeys.getFirst()); dialogService.showErrorDialogAndWait(errorTitle, msg); } - } catch ( - NoDocumentException ex) { + } catch (NoDocumentException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); - } catch ( - DisposedException ex) { + } catch (DisposedException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); - } catch ( - CreationException - | - WrappedTargetException - | - com.sun.star.lang.IllegalArgumentException ex) { + } catch (CreationException + | WrappedTargetException + | com.sun.star.lang.IllegalArgumentException ex) { LOGGER.warn("Could not update bibliography", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } } else if (style instanceof CitationStyle citationStyle) { - final String errorTitle = Localization.lang("Unable to synchronize bibliography"); - try { OOResult odoc = getXTextDocument(); if (testDialog(errorTitle, odoc.asVoidResult())) { @@ -949,30 +942,31 @@ public void guiActionUpdateDocument(List databases, OOStyle style) bibliographyCursor.gotoEnd(false); // Insert bibliography title - String bibliographyTitle = Localization.lang("Bibliography"); - bibliographyCursor.setString(bibliographyTitle + "\n"); + String bibliographyTitle = Localization.lang("References"); + bibliographyCursor.setString("\n"); - // Apply formatting to the title (e.g., make it bold and larger) + // Apply formatting to the title (here, we make it bold and larger) XTextRange titleRange = bibliographyCursor.getStart(); titleRange.setString(bibliographyTitle); XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); titleProps.setPropertyValue("CharWeight", com.sun.star.awt.FontWeight.BOLD); - titleProps.setPropertyValue("CharHeight", 16f); // Adjust the size as needed + titleProps.setPropertyValue("CharHeight", 16f); - // Move cursor to the next line for bibliography entries + // Move cursor to prevent reference mark bleed-out (current implementation) TODO: Remove once bleed-out is fixed bibliographyCursor.goRight((short) 1, false); // Insert bibliography entries - BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(databases.get(0)); // Assuming the first database is the main one - BibEntryTypesManager bibEntryTypesManager = new BibEntryTypesManager(); // You might need to inject this + // BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(databases.getFirst()); + // TODO: Ask Chris if injecting database context is a good idea + BibDatabaseContext bibDatabaseContext = Injector.instantiateModelOrService(BibDatabaseContext.class); + BibEntryTypesManager bibEntryTypesManager = Injector.instantiateModelOrService(BibEntryTypesManager.class); adapter.insertBibliography(doc, bibliographyCursor, citationStyle, citedEntries, bibDatabaseContext, bibEntryTypesManager); } finally { UnoUndo.leaveUndoContext(doc); fcursor.get().restore(doc); } - } catch ( - Exception ex) { + } catch (Exception ex) { LOGGER.warn("Could not create bibliography", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } From 93b153ee7160cb787d7a3b3630dfda4bfc12092a Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 01:48:19 +0530 Subject: [PATCH 19/94] Fix a-tag link text --- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index bc9f0e24974..bc76e046937 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -125,9 +125,10 @@ private String updateSingleCitation(String citation, int currentNumber) { * The transformed HTML can be used for inserting into a LibreOffice document * Context: The HTML produced by CitationStyleGenerator.generateCitation(...) is not directly (completely) parsable by OOTextIntoOO.write(...) * For more details, read the documentation of the write(...) method in the {@link OOTextIntoOO} class. - * Additional information: .... + * Additional Information. * * @param html The HTML string to be transformed into OO-write ready HTML. + * @return The formatted html string */ private String transformHtml(String html) { // Initial clean up of escaped characters From 0750f56c6df2aeb2ec8a6729d69a80f178dc9061 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 02:06:13 +0530 Subject: [PATCH 20/94] Rename functions: less confusing names --- .../openoffice/oocsltext/CSLCitationOOAdapter.java | 10 ++++------ .../logic/openoffice/oocsltext/ReferenceMark.java | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 001a7ab5589..a9ca25cbcac 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -43,14 +43,12 @@ public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationSt String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); - // TODO: constructor injection for style - List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); for (int i = 0; i < citations.size(); i++) { BibEntry entry = entries.get(i); String citation = citations.get(i); - insertCitation(doc, cursor, entry, citation); + writeCitation(doc, cursor, entry, citation); } } @@ -63,11 +61,11 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); for (BibEntry entry : entries) { - insertCitation(doc, cursor, entry, inTextCitation); + writeCitation(doc, cursor, entry, inTextCitation); } } - private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry, String citation) throws Exception { + private void writeCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry, String citation) throws Exception { String citationKey = entry.getCitationKey().orElse(""); int currentNumber = markManager.getCitationNumber(citationKey); @@ -81,7 +79,7 @@ private void insertCitation(XTextDocument doc, XTextCursor cursor, BibEntry entr OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); // Insert the citation text wrapped in a reference mark - mark.insertInText(doc, cursor, ooText); + mark.insertReferenceIntoOO(doc, cursor, ooText); // Move the cursor to the end of the inserted text cursor.collapseToEnd(); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java index e1a2272126a..a599c473458 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java @@ -28,8 +28,8 @@ public ReferenceMark(XTextDocument document, XNamed named, String name) { } } - public void insertInText(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception { - // To debug: mark doesn't wrap around text!?? + public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception { + // TODO: Debug - mark doesn't wrap around text!?? // Insert the text content at the cursor position OOTextIntoOO.write(doc, cursor, ooText); From 38c47310acdf5f0970db3eb0132f95b3ef5717f7 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 02:42:56 +0530 Subject: [PATCH 21/94] Fixing in-text groups - phase 1 --- .../oocsltext/CSLCitationOOAdapter.java | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index a9ca25cbcac..fb9619bdbc7 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; @@ -60,9 +61,44 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); - for (BibEntry entry : entries) { - writeCitation(doc, cursor, entry, inTextCitation); + writeInTextCitation(doc, cursor, entries, inTextCitation); + } + + private void writeInTextCitation(XTextDocument doc, XTextCursor cursor, List entries, String citation) throws Exception { + String formattedCitation = transformHtml(citation); + + if (isNumericStyle) { + formattedCitation = updateMultipleCitations(formattedCitation, entries); + } + + OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); + + // Create a single reference mark for the entire in-text citation + ReferenceMark mark = markManager.createReferenceMark(entries.get(0), "InTextReferenceMark"); + + // Insert the citation text wrapped in a reference mark + mark.insertReferenceIntoOO(doc, cursor, ooText); + + // Move the cursor to the end of the inserted text + cursor.collapseToEnd(); + } + + private String updateMultipleCitations(String citation, List entries) { + Pattern pattern = Pattern.compile("\\[(.*?)\\]"); + Matcher matcher = pattern.matcher(citation); + StringBuffer sb = new StringBuffer(); + + while (matcher.find()) { + String[] numbers = matcher.group(1).split(","); + List updatedNumbers = entries.stream() + .map(entry -> String.valueOf(markManager.getCitationNumber(entry.getCitationKey().orElse("")))) + .collect(Collectors.toList()); + + String replacement = "[" + String.join(",", updatedNumbers) + "]"; + matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); } + matcher.appendTail(sb); + return sb.toString(); } private void writeCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry, String citation) throws Exception { From a04d82689140f7e8f1a6d874e6dfa3aa4b57838e Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 03:21:29 +0530 Subject: [PATCH 22/94] in-text citations fix phase 2 --- .../oocsltext/CSLCitationOOAdapter.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index fb9619bdbc7..f85e955e0dd 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -3,7 +3,6 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; @@ -59,13 +58,11 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); + // Generate a single in-text citation for all entries String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); - writeInTextCitation(doc, cursor, entries, inTextCitation); - } - - private void writeInTextCitation(XTextDocument doc, XTextCursor cursor, List entries, String citation) throws Exception { - String formattedCitation = transformHtml(citation); + String formattedCitation = transformHtml(inTextCitation); + System.out.println(formattedCitation); if (isNumericStyle) { formattedCitation = updateMultipleCitations(formattedCitation, entries); @@ -75,6 +72,7 @@ private void writeInTextCitation(XTextDocument doc, XTextCursor cursor, List entries) { - Pattern pattern = Pattern.compile("\\[(.*?)\\]"); + Pattern pattern = Pattern.compile("(\\D*)(\\d+)(\\D*)"); Matcher matcher = pattern.matcher(citation); - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); + int entryIndex = 0; - while (matcher.find()) { - String[] numbers = matcher.group(1).split(","); - List updatedNumbers = entries.stream() - .map(entry -> String.valueOf(markManager.getCitationNumber(entry.getCitationKey().orElse("")))) - .collect(Collectors.toList()); + while (matcher.find() && entryIndex < entries.size()) { + String prefix = matcher.group(1); + String suffix = matcher.group(3); + + int currentNumber = markManager.getCitationNumber(entries.get(entryIndex).getCitationKey().orElse("")); - String replacement = "[" + String.join(",", updatedNumbers) + "]"; - matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); + matcher.appendReplacement(sb, Matcher.quoteReplacement(prefix + currentNumber + suffix)); + entryIndex++; } matcher.appendTail(sb); return sb.toString(); From 622fda69909abdf16bfdeeacbf50e6b26145b614 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 03:49:56 +0530 Subject: [PATCH 23/94] Broken implementation for future reference --- .../oocsltext/CSLCitationOOAdapter.java | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index f85e955e0dd..f04dae39b57 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,5 +1,6 @@ package org.jabref.logic.openoffice.oocsltext; +import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -70,17 +71,58 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); - // Create a single reference mark for the entire in-text citation - ReferenceMark mark = markManager.createReferenceMark(entries.get(0), "InTextReferenceMark"); - System.out.println(ooText); - - // Insert the citation text wrapped in a reference mark - mark.insertReferenceIntoOO(doc, cursor, ooText); + // Insert the citation text with multiple reference marks + insertMultipleReferenceMarks(doc, cursor, entries, ooText); // Move the cursor to the end of the inserted text cursor.collapseToEnd(); } + private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, List entries, OOText ooText) throws Exception { + String fullCitation = ooText.toString(); + + // Split the citation into parts + List citationParts = splitCitation(fullCitation); + + int lastEnd = 0; + for (int i = 0; i < Math.min(citationParts.size(), entries.size()); i++) { + String part = citationParts.get(i); + int start = fullCitation.indexOf(part, lastEnd); + + // Insert text before the current part + if (start > lastEnd) { + String beforeText = fullCitation.substring(lastEnd, start); + OOText beforeOOText = OOFormat.setLocaleNone(OOText.fromString(beforeText)); + OOTextIntoOO.write(doc, cursor, beforeOOText); + } + + // Create and insert a reference mark for the current entry + BibEntry entry = entries.get(i); + ReferenceMark mark = markManager.createReferenceMark(entry, "InTextReferenceMark"); + OOText partOOText = OOFormat.setLocaleNone(OOText.fromString(part)); + mark.insertReferenceIntoOO(doc, cursor, partOOText); + + lastEnd = start + part.length(); + } + + // Insert any remaining text after the last part + if (lastEnd < fullCitation.length()) { + String afterText = fullCitation.substring(lastEnd); + OOText afterOOText = OOFormat.setLocaleNone(OOText.fromString(afterText)); + OOTextIntoOO.write(doc, cursor, afterOOText); + } + } + + private List splitCitation(String citation) { + List parts = new ArrayList<>(); + Pattern pattern = Pattern.compile("\\[\\d+\\]|\\([^)]+\\)|[^,;]+"); + Matcher matcher = pattern.matcher(citation); + while (matcher.find()) { + parts.add(matcher.group()); + } + return parts; + } + private String updateMultipleCitations(String citation, List entries) { Pattern pattern = Pattern.compile("(\\D*)(\\d+)(\\D*)"); Matcher matcher = pattern.matcher(citation); From f723bf8b49210f51e2b516304336e16f3e30a082 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 04:23:47 +0530 Subject: [PATCH 24/94] Working model --- .../oocsltext/CSLCitationOOAdapter.java | 36 +++++-------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index f04dae39b57..dcf3ede9771 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -79,38 +79,18 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se } private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, List entries, OOText ooText) throws Exception { - String fullCitation = ooText.toString(); + // Insert the entire citation text as-is + OOTextIntoOO.write(doc, cursor, ooText); - // Split the citation into parts - List citationParts = splitCitation(fullCitation); - - int lastEnd = 0; - for (int i = 0; i < Math.min(citationParts.size(), entries.size()); i++) { - String part = citationParts.get(i); - int start = fullCitation.indexOf(part, lastEnd); - - // Insert text before the current part - if (start > lastEnd) { - String beforeText = fullCitation.substring(lastEnd, start); - OOText beforeOOText = OOFormat.setLocaleNone(OOText.fromString(beforeText)); - OOTextIntoOO.write(doc, cursor, beforeOOText); - } - - // Create and insert a reference mark for the current entry - BibEntry entry = entries.get(i); + // Insert reference marks for each entry after the citation + for (BibEntry entry : entries) { ReferenceMark mark = markManager.createReferenceMark(entry, "InTextReferenceMark"); - OOText partOOText = OOFormat.setLocaleNone(OOText.fromString(part)); - mark.insertReferenceIntoOO(doc, cursor, partOOText); - - lastEnd = start + part.length(); + OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); + mark.insertReferenceIntoOO(doc, cursor, emptyOOText); } - // Insert any remaining text after the last part - if (lastEnd < fullCitation.length()) { - String afterText = fullCitation.substring(lastEnd); - OOText afterOOText = OOFormat.setLocaleNone(OOText.fromString(afterText)); - OOTextIntoOO.write(doc, cursor, afterOOText); - } + // Move the cursor to the end of the inserted text + cursor.collapseToEnd(); } private List splitCitation(String citation) { From d105eaa7373bf78d131d73c7ff8cb9ef75aef2b5 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 06:06:18 +0530 Subject: [PATCH 25/94] Rename: CSL Reference Mark Model & Handler files --- .../oocsltext/CSLCitationOOAdapter.java | 8 ++++---- ...ferenceMark.java => CSLReferenceMark.java} | 4 ++-- ...ager.java => CSLReferenceMarkManager.java} | 20 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) rename src/main/java/org/jabref/logic/openoffice/oocsltext/{ReferenceMark.java => CSLReferenceMark.java} (93%) rename src/main/java/org/jabref/logic/openoffice/oocsltext/{MarkManager.java => CSLReferenceMarkManager.java} (81%) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index dcf3ede9771..f6d8c01de08 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -26,12 +26,12 @@ public class CSLCitationOOAdapter { private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; - private MarkManager markManager; + private CSLReferenceMarkManager markManager; private boolean isNumericStyle = false; public CSLCitationOOAdapter(XTextDocument doc) throws Exception { this.document = doc; - this.markManager = new MarkManager(doc); + this.markManager = new CSLReferenceMarkManager(doc); } public void readExistingMarks() throws Exception { @@ -84,7 +84,7 @@ private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, // Insert reference marks for each entry after the citation for (BibEntry entry : entries) { - ReferenceMark mark = markManager.createReferenceMark(entry, "InTextReferenceMark"); + CSLReferenceMark mark = markManager.createReferenceMark(entry, "InTextReferenceMark"); OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); mark.insertReferenceIntoOO(doc, cursor, emptyOOText); } @@ -126,7 +126,7 @@ private void writeCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry String citationKey = entry.getCitationKey().orElse(""); int currentNumber = markManager.getCitationNumber(citationKey); - ReferenceMark mark = markManager.createReferenceMark(entry, "ReferenceMark"); + CSLReferenceMark mark = markManager.createReferenceMark(entry, "CSLReferenceMark"); String formattedCitation; if (isNumericStyle) { formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java similarity index 93% rename from src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java rename to src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index a599c473458..2da362b9d87 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/ReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -10,14 +10,14 @@ import com.sun.star.text.XTextRange; import com.sun.star.uno.UnoRuntime; -public class ReferenceMark { +public class CSLReferenceMark { private final XTextDocument document; private final XNamed named; private final String name; private XTextContent textContent; private String citationKey; - public ReferenceMark(XTextDocument document, XNamed named, String name) { + public CSLReferenceMark(XTextDocument document, XNamed named, String name) { this.document = document; this.named = named; this.name = name; diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java similarity index 81% rename from src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java rename to src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index 64c83b8d8ec..d9fa3b1bb08 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/MarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -15,16 +15,16 @@ import com.sun.star.text.XTextDocument; import com.sun.star.uno.UnoRuntime; -public class MarkManager { - private final HashMap marksByName; - private final ArrayList marksByID; - private final IdentityHashMap idsByMark; +public class CSLReferenceMarkManager { + private final HashMap marksByName; + private final ArrayList marksByID; + private final IdentityHashMap idsByMark; private final XTextDocument document; private final XMultiServiceFactory factory; private HashMap citationKeyToNumber; private int highestCitationNumber = 0; - public MarkManager(XTextDocument document) throws Exception { + public CSLReferenceMarkManager(XTextDocument document) throws Exception { this.document = document; this.factory = UnoRuntime.queryInterface(XMultiServiceFactory.class, document); this.marksByName = new HashMap<>(); @@ -39,7 +39,7 @@ public void readExistingMarks() throws Exception { for (String name : marks.getElementNames()) { if (name.startsWith(CSLCitationOOAdapter.PREFIXES[0])) { XNamed named = UnoRuntime.queryInterface(XNamed.class, marks.getByName(name)); - ReferenceMark mark = new ReferenceMark(document, named, name); + CSLReferenceMark mark = new CSLReferenceMark(document, named, name); addMark(mark); updateCitationInfo(name); } @@ -57,7 +57,7 @@ private void updateCitationInfo(String name) { } } - public void addMark(ReferenceMark mark) { + public void addMark(CSLReferenceMark mark) { marksByName.put(mark.getName(), mark); idsByMark.put(mark, marksByID.size()); marksByID.add(mark); @@ -71,16 +71,16 @@ public int getCitationNumber(String citationKey) { }); } - public ReferenceMark createReferenceMark(BibEntry entry, String fieldType) throws Exception { + public CSLReferenceMark createReferenceMark(BibEntry entry, String fieldType) throws Exception { String citationKey = entry.getCitationKey().orElse(""); int citationNumber = getCitationNumber(citationKey); String name = CSLCitationOOAdapter.PREFIXES[0] + citationKey + " RND" + citationNumber; - Object mark = factory.createInstance("com.sun.star.text.ReferenceMark"); + Object mark = factory.createInstance("com.sun.star.text.CSLReferenceMark"); XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); named.setName(name); - ReferenceMark referenceMark = new ReferenceMark(document, named, name); + CSLReferenceMark referenceMark = new CSLReferenceMark(document, named, name); addMark(referenceMark); return referenceMark; From e8def54da211b824364b13001f2de065e58130fa Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 06:09:00 +0530 Subject: [PATCH 26/94] Merge, order of imports --- .../jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 0dc94fd6f99..a652496ff9f 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,7 +1,7 @@ package org.jabref.logic.openoffice.oocsltext; -import java.util.Comparator; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; From 38447c7d6eedabc4d67da14a0697bb30ab79faf6 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 15:43:09 +0530 Subject: [PATCH 27/94] Fix: Local storage of last citation number --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 7 ++++--- .../openoffice/oocsltext/CSLReferenceMarkManager.java | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 1687b077e0f..4a7e9dfe614 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -612,7 +612,8 @@ public void guiActionInsertEntry(List entries, UnoUndo.enterUndoContext(doc, "Insert citation"); if (style instanceof CitationStyle citationStyle) { // Handle insertion of CSL Style citations - CSLCitationOOAdapter adapter = getOrCreateCSLCitationOOAdapter(doc); + CSLCitationOOAdapter adapter = new CSLCitationOOAdapter(doc); + adapter.readExistingMarks(); if (citationType == CitationType.AUTHORYEAR_INTEXT) { adapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } else { @@ -937,7 +938,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) bibliographyCursor.gotoEnd(false); // Insert bibliography title - String bibliographyTitle = Localization.lang("References"); + String bibliographyTitle = Localization.lang("\nReferences"); bibliographyCursor.setString("\n"); // Apply formatting to the title (here, we make it bold and larger) @@ -971,8 +972,8 @@ public void guiActionUpdateDocument(List databases, OOStyle style) private CSLCitationOOAdapter getOrCreateCSLCitationOOAdapter(XTextDocument doc) throws Exception { if (cslCitationOOAdapter == null) { cslCitationOOAdapter = new CSLCitationOOAdapter(doc); - cslCitationOOAdapter.readExistingMarks(); } + cslCitationOOAdapter.readExistingMarks(); return cslCitationOOAdapter; } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index f8cce1828d2..c61d3d1cac2 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -124,7 +124,7 @@ public CSLReferenceMark createReferenceMark(BibEntry entry, String fieldType) th int citationNumber = getCitationNumber(citationKey); String name = CSLCitationOOAdapter.PREFIXES[0] + citationKey + " RND" + citationNumber; - Object mark = factory.createInstance("com.sun.star.text.CSLReferenceMark"); + Object mark = factory.createInstance("com.sun.star.text.ReferenceMark"); XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); named.setName(name); From 439e2d4f92ffe20682e634ab36c84fafd2ae9395 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 15:50:49 +0530 Subject: [PATCH 28/94] Remove unused initializer --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 8 -------- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 4 ++-- .../openoffice/oocsltext/CSLReferenceMarkManager.java | 2 +- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 4a7e9dfe614..aa3020e92af 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -968,12 +968,4 @@ public void guiActionUpdateDocument(List databases, OOStyle style) } } } - - private CSLCitationOOAdapter getOrCreateCSLCitationOOAdapter(XTextDocument doc) throws Exception { - if (cslCitationOOAdapter == null) { - cslCitationOOAdapter = new CSLCitationOOAdapter(doc); - } - cslCitationOOAdapter.readExistingMarks(); - return cslCitationOOAdapter; - } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index a652496ff9f..0c6665bd003 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -88,7 +88,7 @@ private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, // Insert reference marks for each entry after the citation for (BibEntry entry : entries) { - CSLReferenceMark mark = markManager.createReferenceMark(entry, "InTextReferenceMark"); + CSLReferenceMark mark = markManager.createReferenceMark(entry); OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); mark.insertReferenceIntoOO(doc, cursor, emptyOOText); } @@ -130,7 +130,7 @@ private void writeCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry String citationKey = entry.getCitationKey().orElse(""); int currentNumber = markManager.getCitationNumber(citationKey); - CSLReferenceMark mark = markManager.createReferenceMark(entry, "CSLReferenceMark"); + CSLReferenceMark mark = markManager.createReferenceMark(entry); String formattedCitation; if (isNumericStyle) { formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index c61d3d1cac2..3287a517dee 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -119,7 +119,7 @@ public int getCitationNumber(String citationKey) { }); } - public CSLReferenceMark createReferenceMark(BibEntry entry, String fieldType) throws Exception { + public CSLReferenceMark createReferenceMark(BibEntry entry) throws Exception { String citationKey = entry.getCitationKey().orElse(""); int citationNumber = getCitationNumber(citationKey); From 64995468e88abbf464c3dbcf58d442832ec61f24 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 16:00:36 +0530 Subject: [PATCH 29/94] Refactor begin --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 3 +++ .../jabref/logic/openoffice/oocsltext/CSLReferenceMark.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index aa3020e92af..5a5ed762640 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -612,8 +612,10 @@ public void guiActionInsertEntry(List entries, UnoUndo.enterUndoContext(doc, "Insert citation"); if (style instanceof CitationStyle citationStyle) { // Handle insertion of CSL Style citations + CSLCitationOOAdapter adapter = new CSLCitationOOAdapter(doc); adapter.readExistingMarks(); + if (citationType == CitationType.AUTHORYEAR_INTEXT) { adapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } else { @@ -621,6 +623,7 @@ public void guiActionInsertEntry(List entries, } } else if (style instanceof JStyle jStyle) { // Handle insertion of JStyle citations + EditInsert.insertCitationGroup(doc, frontend.get(), cursor.get(), diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index 2da362b9d87..f8b62b941b2 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -24,7 +24,7 @@ public CSLReferenceMark(XTextDocument document, XNamed named, String name) { this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); String[] parts = name.split(" "); if (parts.length >= 2) { - this.citationKey = parts[1]; + this.citationKey = parts[1]; // Format: JABREF_{citationKey} RND{citationNumber} } } From c4926285c8cb3e9f8dece7f6fad8ccfa5e703f70 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 17:06:45 +0530 Subject: [PATCH 30/94] Refactoring - 2 --- .../org/jabref/gui/openoffice/OOBibBase.java | 6 ++--- .../oocsltext/CSLCitationOOAdapter.java | 23 ++++--------------- .../oocsltext/CSLReferenceMark.java | 12 ++++------ .../oocsltext/CSLReferenceMarkManager.java | 11 ++++----- 4 files changed, 17 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 5a5ed762640..1eedce6b364 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -617,9 +617,9 @@ public void guiActionInsertEntry(List entries, adapter.readExistingMarks(); if (citationType == CitationType.AUTHORYEAR_INTEXT) { - adapter.insertInText(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + adapter.insertInText(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } else { - adapter.insertBibliography(doc, cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + adapter.insertBibliography(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } } else if (style instanceof JStyle jStyle) { // Handle insertion of JStyle citations @@ -960,7 +960,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) BibDatabaseContext bibDatabaseContext = Injector.instantiateModelOrService(BibDatabaseContext.class); BibEntryTypesManager bibEntryTypesManager = Injector.instantiateModelOrService(BibEntryTypesManager.class); - adapter.insertBibliography(doc, bibliographyCursor, citationStyle, citedEntries, bibDatabaseContext, bibEntryTypesManager); + adapter.insertBibliography(bibliographyCursor, citationStyle, citedEntries, bibDatabaseContext, bibEntryTypesManager); } finally { UnoUndo.leaveUndoContext(doc); fcursor.get().restore(doc); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 0c6665bd003..e18ce207672 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,6 +1,5 @@ package org.jabref.logic.openoffice.oocsltext; -import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; @@ -23,11 +22,10 @@ public class CSLCitationOOAdapter { public static final String[] PREFIXES = {"JABREF_", "CSL_"}; - public static final int REFMARK_ADD_CHARS = 8; private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; - private CSLReferenceMarkManager markManager; + private final CSLReferenceMarkManager markManager; private boolean isNumericStyle = false; public CSLCitationOOAdapter(XTextDocument doc) throws Exception { @@ -39,7 +37,7 @@ public void readExistingMarks() throws Exception { markManager.readExistingMarks(); } - public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) + public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { String style = selectedStyle.getSource(); @@ -53,11 +51,11 @@ public void insertBibliography(XTextDocument doc, XTextCursor cursor, CitationSt for (int i = 0; i < citations.size(); i++) { BibEntry entry = entries.get(i); String citation = citations.get(i); - writeCitation(doc, cursor, entry, citation); + writeCitation(document, cursor, entry, citation); } } - public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) + public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { String style = selectedStyle.getSource(); @@ -67,7 +65,6 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); String formattedCitation = transformHtml(inTextCitation); - System.out.println(formattedCitation); if (isNumericStyle) { formattedCitation = updateMultipleCitations(formattedCitation, entries); @@ -76,7 +73,7 @@ public void insertInText(XTextDocument doc, XTextCursor cursor, CitationStyle se OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); // Insert the citation text with multiple reference marks - insertMultipleReferenceMarks(doc, cursor, entries, ooText); + insertMultipleReferenceMarks(document, cursor, entries, ooText); // Move the cursor to the end of the inserted text cursor.collapseToEnd(); @@ -97,16 +94,6 @@ private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, cursor.collapseToEnd(); } - private List splitCitation(String citation) { - List parts = new ArrayList<>(); - Pattern pattern = Pattern.compile("\\[\\d+\\]|\\([^)]+\\)|[^,;]+"); - Matcher matcher = pattern.matcher(citation); - while (matcher.find()) { - parts.add(matcher.group()); - } - return parts; - } - private String updateMultipleCitations(String citation, List entries) { Pattern pattern = Pattern.compile("(\\D*)(\\d+)(\\D*)"); Matcher matcher = pattern.matcher(citation); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index f8b62b941b2..46954dffad3 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -11,20 +11,16 @@ import com.sun.star.uno.UnoRuntime; public class CSLReferenceMark { - private final XTextDocument document; - private final XNamed named; private final String name; - private XTextContent textContent; + private final XTextContent textContent; private String citationKey; - public CSLReferenceMark(XTextDocument document, XNamed named, String name) { - this.document = document; - this.named = named; + public CSLReferenceMark(XNamed named, String name) { this.name = name; this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); String[] parts = name.split(" "); if (parts.length >= 2) { - this.citationKey = parts[1]; // Format: JABREF_{citationKey} RND{citationNumber} + this.citationKey = parts[0]; // Format: JABREF_{citationKey} RND{citationNumber} } } @@ -38,7 +34,7 @@ public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText XTextRange start = cursor.getStart(); XTextRange end = cursor.getEnd(); cursor.gotoRange(start, false); - cursor.gotoRange(end, true); + // cursor.gotoRange(end, true); // Attach the reference mark to this range textContent.attach(cursor); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index 3287a517dee..b358edf933c 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -22,10 +22,9 @@ public class CSLReferenceMarkManager { private final IdentityHashMap idsByMark; private final XTextDocument document; private final XMultiServiceFactory factory; - private HashMap citationKeyToNumber; + private final HashMap citationKeyToNumber; private int highestCitationNumber = 0; - private Map citationOrder = new HashMap<>(); - private int citationCounter = 0; + private final Map citationOrder = new HashMap<>(); public CSLReferenceMarkManager(XTextDocument document) throws Exception { this.document = document; @@ -41,7 +40,7 @@ public void readExistingMarks() throws Exception { XNameAccess marks = supplier.getReferenceMarks(); citationOrder.clear(); - citationCounter = 0; + int citationCounter = 0; for (String name : marks.getElementNames()) { String citationKey = extractCitationKey(name); @@ -49,7 +48,7 @@ public void readExistingMarks() throws Exception { citationOrder.putIfAbsent(citationKey, ++citationCounter); XNamed named = UnoRuntime.queryInterface(XNamed.class, marks.getByName(name)); - CSLReferenceMark mark = new CSLReferenceMark(document, named, name); + CSLReferenceMark mark = new CSLReferenceMark(named, name); addMark(mark); } } @@ -128,7 +127,7 @@ public CSLReferenceMark createReferenceMark(BibEntry entry) throws Exception { XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); named.setName(name); - CSLReferenceMark referenceMark = new CSLReferenceMark(document, named, name); + CSLReferenceMark referenceMark = new CSLReferenceMark(named, name); addMark(referenceMark); return referenceMark; From ac09f0ab6bef9b3049c774e66ca9b8970a6301a1 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 17:46:48 +0530 Subject: [PATCH 31/94] Wrap reference marks around bibliographic citations --- .../oocsltext/CSLReferenceMark.java | 30 +++++++++++++------ .../oocsltext/CSLReferenceMarkManager.java | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index 46954dffad3..4b99fade267 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -14,30 +14,42 @@ public class CSLReferenceMark { private final String name; private final XTextContent textContent; private String citationKey; + private String citationNumber; public CSLReferenceMark(XNamed named, String name) { this.name = name; this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); + + // Format: JABREF_{citationKey} RND{citationNumber} String[] parts = name.split(" "); - if (parts.length >= 2) { - this.citationKey = parts[0]; // Format: JABREF_{citationKey} RND{citationNumber} + + if (parts.length >= 2 && parts[0].startsWith("JABREF_") && parts[1].startsWith("RND")) { + this.citationKey = parts[0].substring(7); + this.citationNumber = parts[1].substring(3); } } public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception { - // TODO: Debug - mark doesn't wrap around text!?? + // Create a text range for the start position + XTextRange startRange = cursor.getStart(); // Insert the text content at the cursor position OOTextIntoOO.write(doc, cursor, ooText); - // Create a text range covering the just-inserted text - XTextRange start = cursor.getStart(); - XTextRange end = cursor.getEnd(); - cursor.gotoRange(start, false); - // cursor.gotoRange(end, true); + // Create a text range for the end position + XTextRange endRange = cursor.getEnd(); + + // Move the cursor back to the start position + cursor.gotoRange(startRange, false); - // Attach the reference mark to this range + // Select the text by moving to the end position + cursor.gotoRange(endRange, true); + + // Attach the reference mark to the selected range textContent.attach(cursor); + + // Move the cursor to the end of the inserted text + cursor.gotoRange(endRange, false); } public String getName() { diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index b358edf933c..8b34afe7652 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -26,7 +26,7 @@ public class CSLReferenceMarkManager { private int highestCitationNumber = 0; private final Map citationOrder = new HashMap<>(); - public CSLReferenceMarkManager(XTextDocument document) throws Exception { + public CSLReferenceMarkManager(XTextDocument document) { this.document = document; this.factory = UnoRuntime.queryInterface(XMultiServiceFactory.class, document); this.marksByName = new HashMap<>(); From c19ecaab93b7cc9f7b75a367cdde841a6aa0f8a1 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 4 Aug 2024 22:25:05 +0530 Subject: [PATCH 32/94] Fix order of citations --- .../oocsltext/CSLCitationOOAdapter.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index e18ce207672..4133c0c7cdc 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,6 +1,5 @@ package org.jabref.logic.openoffice.oocsltext; -import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -44,15 +43,18 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, isNumericStyle = selectedStyle.isNumericStyle(); // Sort entries based on their order of appearance in the document - entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); - - List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); - - for (int i = 0; i < citations.size(); i++) { - BibEntry entry = entries.get(i); - String citation = citations.get(i); + // entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); + for (BibEntry entry: entries) { + String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); writeCitation(document, cursor, entry, citation); } + // List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); + +// for (int i = 0; i < citations.size(); i++) { +// BibEntry entry = entries.get(i); +// String citation = citations.get(i); +// writeCitation(document, cursor, entry, citation); +// } } public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) From dc97f117b74845762c3e7727338aac9873dad907 Mon Sep 17 00:00:00 2001 From: subhramit Date: Mon, 5 Aug 2024 00:43:13 +0530 Subject: [PATCH 33/94] Fix updateBibliography order --- .../oocsltext/CSLCitationOOAdapter.java | 3 +- .../oocsltext/CSLReferenceMark.java | 32 +++++++++---------- .../oocsltext/CSLReferenceMarkManager.java | 27 +++------------- 3 files changed, 22 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 4133c0c7cdc..c476cd2200c 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,5 +1,6 @@ package org.jabref.logic.openoffice.oocsltext; +import java.util.Comparator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -43,7 +44,7 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, isNumericStyle = selectedStyle.isNumericStyle(); // Sort entries based on their order of appearance in the document - // entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); + entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); for (BibEntry entry: entries) { String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); writeCitation(document, cursor, entry, citation); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index 4b99fade267..158e1bba55b 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -15,40 +15,32 @@ public class CSLReferenceMark { private final XTextContent textContent; private String citationKey; private String citationNumber; + private String uniqueId; public CSLReferenceMark(XNamed named, String name) { this.name = name; this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); - // Format: JABREF_{citationKey} RND{citationNumber} + // Format: JABREF_{citationKey} CID_{citationNumber} {uniqueId} String[] parts = name.split(" "); - if (parts.length >= 2 && parts[0].startsWith("JABREF_") && parts[1].startsWith("RND")) { + if (parts.length >= 3 && parts[0].startsWith("JABREF_") && parts[1].startsWith("CID_")) { this.citationKey = parts[0].substring(7); - this.citationNumber = parts[1].substring(3); + this.citationNumber = parts[1].substring(4); + this.uniqueId = parts[2]; + System.out.println(citationKey); + System.out.println(citationNumber); + System.out.println(uniqueId); } } public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception { - // Create a text range for the start position XTextRange startRange = cursor.getStart(); - - // Insert the text content at the cursor position OOTextIntoOO.write(doc, cursor, ooText); - - // Create a text range for the end position XTextRange endRange = cursor.getEnd(); - - // Move the cursor back to the start position cursor.gotoRange(startRange, false); - - // Select the text by moving to the end position cursor.gotoRange(endRange, true); - - // Attach the reference mark to the selected range textContent.attach(cursor); - - // Move the cursor to the end of the inserted text cursor.gotoRange(endRange, false); } @@ -63,4 +55,12 @@ public XTextContent getTextContent() { public String getCitationKey() { return citationKey; } + + public String getCitationNumber() { + return citationNumber; + } + + public String getUniqueId() { + return uniqueId; + } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index 8b34afe7652..da01dcf6325 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.IdentityHashMap; import java.util.Map; +import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -54,47 +55,26 @@ public void readExistingMarks() throws Exception { } } - /** - * Extracts the citation key from a reference mark name. - * - * @param name The name of the reference mark - * @return The extracted citation key, or an empty string if no key could be extracted - */ private String extractCitationKey(String name) { - // Check if the name starts with one of the known prefixes for (String prefix : CSLCitationOOAdapter.PREFIXES) { if (name.startsWith(prefix)) { - // Remove the prefix String withoutPrefix = name.substring(prefix.length()); - - // Split the remaining string by space String[] parts = withoutPrefix.split("\\s+"); - if (parts.length > 0) { - // The first part should be the citation key String key = parts[0]; - - // Remove any non-alphanumeric characters from the start and end key = key.replaceAll("^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$", ""); - - // If we have a non-empty key, return it if (!key.isEmpty()) { return key; } } - - // If we couldn't extract a key after removing the prefix, - // no need to check other prefixes break; } } - - // If no key could be extracted, return an empty string return ""; } private void updateCitationInfo(String name) { - Pattern pattern = Pattern.compile("JABREF_(.+) RND(\\d+)"); // Format: JABREF_{citationKey} RND{citationNumber} + Pattern pattern = Pattern.compile("JABREF_(.+) CID_(\\d+) (.+)"); // Updated pattern Matcher matcher = pattern.matcher(name); if (matcher.find()) { String citationKey = matcher.group(1); @@ -121,8 +101,9 @@ public int getCitationNumber(String citationKey) { public CSLReferenceMark createReferenceMark(BibEntry entry) throws Exception { String citationKey = entry.getCitationKey().orElse(""); int citationNumber = getCitationNumber(citationKey); + String uniqueId = UUID.randomUUID().toString().substring(0, 8); // Generate a unique ID - String name = CSLCitationOOAdapter.PREFIXES[0] + citationKey + " RND" + citationNumber; + String name = CSLCitationOOAdapter.PREFIXES[0] + citationKey + " CID_" + citationNumber + " " + uniqueId; Object mark = factory.createInstance("com.sun.star.text.ReferenceMark"); XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); named.setName(name); From e0f281e0c48babfe698073dabe1aa592914b736e Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 5 Aug 2024 12:05:48 +0200 Subject: [PATCH 34/94] Simplify getCitationNumber(String citationKey) --- .../logic/openoffice/oocsltext/CSLReferenceMarkManager.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index da01dcf6325..899b3160f5b 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -92,10 +92,7 @@ public void addMark(CSLReferenceMark mark) { } public int getCitationNumber(String citationKey) { - return citationKeyToNumber.computeIfAbsent(citationKey, k -> { - highestCitationNumber++; - return highestCitationNumber; - }); + return citationKeyToNumber.computeIfAbsent(citationKey, k -> ++highestCitationNumber); } public CSLReferenceMark createReferenceMark(BibEntry entry) throws Exception { From 48d2f4d26ded38fcfb5891623dd86e8b0e56ac75 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 5 Aug 2024 12:46:39 +0200 Subject: [PATCH 35/94] Improve CSLReferenceMark --- build.gradle | 4 + src/main/java/module-info.java | 1 + .../logic/openoffice/ReferenceMark.java | 90 +++++++++++++++++++ .../oocsltext/CSLReferenceMark.java | 63 +++++++------ .../oocsltext/CSLReferenceMarkManager.java | 61 ++++--------- .../logic/openoffice/ReferenceMarkTest.java | 32 +++++++ 6 files changed, 177 insertions(+), 74 deletions(-) create mode 100644 src/main/java/org/jabref/logic/openoffice/ReferenceMark.java create mode 100644 src/test/java/org/jabref/logic/openoffice/ReferenceMarkTest.java diff --git a/build.gradle b/build.gradle index dcdc107f4fa..61b247fa5f1 100644 --- a/build.gradle +++ b/build.gradle @@ -179,8 +179,12 @@ dependencies { implementation 'commons-cli:commons-cli:1.8.0' + // region: LibreOffice implementation 'org.libreoffice:unoloader:24.2.3' implementation 'org.libreoffice:libreoffice:24.2.3' + // Required for ID generation + implementation 'io.github.thibaultmeyer:cuid:2.0.3' + // endregion implementation 'io.github.java-diff-utils:java-diff-utils:4.12' implementation 'info.debatty:java-string-similarity:2.0.0' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 06bfb4c6c41..b68acaf55e0 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -161,6 +161,7 @@ requires transitive org.jspecify; // region: other libraries (alphabetically) + requires cuid; requires dd.plist; requires mslinks; requires org.antlr.antlr4.runtime; diff --git a/src/main/java/org/jabref/logic/openoffice/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/ReferenceMark.java new file mode 100644 index 00000000000..b9f3fd449cd --- /dev/null +++ b/src/main/java/org/jabref/logic/openoffice/ReferenceMark.java @@ -0,0 +1,90 @@ +package org.jabref.logic.openoffice; + +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.jabref.logic.openoffice.oocsltext.CSLCitationOOAdapter; + +import io.github.thibaultmeyer.cuid.CUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * See {@link CSLCitationOOAdapter#PREFIXES} for the prefix(es) used to identify reference marks. + */ +public class ReferenceMark { + private static final Logger LOGGER = LoggerFactory.getLogger(ReferenceMark.class); + + private static final Pattern REFERENCE_MARK_FORMAT = Pattern.compile("^JABREF_(\\w+) CID_(\\w+) (\\w+)$"); + private final String name; + + private String citationKey; + private Integer citationNumber; + private String uniqueId; + + /** + * @param name Format: JABREF_{citationKey} CID_{citationNumber} {uniqueId} + */ + public ReferenceMark(String name) { + this.name = name; + + Matcher matcher = getMatcher(name); + if (!matcher.matches()) { + LOGGER.warn("CSLReferenceMark: name={} does not match pattern. Assuming random values", name); + this.citationKey = CUID.randomCUID2(8).toString(); + this.citationNumber = 0; + this.uniqueId = this.citationKey; + return; + } + + this.citationKey = matcher.group(1); + this.citationNumber = Integer.parseInt(matcher.group(2)); + this.uniqueId = matcher.group(3); + + LOGGER.debug("CSLReferenceMark: citationKey={} citationNumber={} uniqueId={}", getCitationKey(), getCitationNumber(), getUniqueId()); + } + + public ReferenceMark(String name, String citationKey, Integer citationNumber, String uniqueId) { + this.name = name; + this.citationKey = citationKey; + this.citationNumber = citationNumber; + this.uniqueId = uniqueId; + } + + private ReferenceMark(String name, String citationKey, String citationNumber, String uniqueId) { + this(name, citationKey, Integer.parseInt(citationNumber), uniqueId); + } + + private static Matcher getMatcher(String name) { + return REFERENCE_MARK_FORMAT.matcher(name); + } + + public String getName() { + return name; + } + + /** + * The BibTeX citation key + */ + public String getCitationKey() { + return citationKey; + } + + public Integer getCitationNumber() { + return citationNumber; + } + + public String getUniqueId() { + return uniqueId; + } + + public static Optional of(String name) { + Matcher matcher = getMatcher(name); + if (!matcher.matches()) { + return Optional.empty(); + } + + return Optional.of(new ReferenceMark(name, matcher.group(1), matcher.group(2), matcher.group(3))); + } +} diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index 158e1bba55b..3927a0033b6 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -1,40 +1,51 @@ package org.jabref.logic.openoffice.oocsltext; +import org.jabref.logic.openoffice.ReferenceMark; import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; +import org.jabref.model.openoffice.uno.CreationException; import com.sun.star.container.XNamed; +import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.text.XTextContent; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import com.sun.star.text.XTextRange; +import com.sun.star.uno.Exception; import com.sun.star.uno.UnoRuntime; +import io.github.thibaultmeyer.cuid.CUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * Class to handle a reference mark. See {@link CSLReferenceMarkManager} for the management of all reference marks. + */ public class CSLReferenceMark { - private final String name; + + private static final Logger LOGGER = LoggerFactory.getLogger(CSLReferenceMark.class); + + private final ReferenceMark referenceMark; private final XTextContent textContent; - private String citationKey; - private String citationNumber; - private String uniqueId; - public CSLReferenceMark(XNamed named, String name) { - this.name = name; - this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); + public CSLReferenceMark(XNamed named, ReferenceMark referenceMark) { + this.referenceMark = referenceMark; + textContent = UnoRuntime.queryInterface(XTextContent.class, named); + } - // Format: JABREF_{citationKey} CID_{citationNumber} {uniqueId} - String[] parts = name.split(" "); + public CSLReferenceMark(XNamed named, String name, String citationKey, Integer citationNumber, String uniqueId) { + referenceMark = new ReferenceMark(name, citationKey, citationNumber, uniqueId); + this.textContent = UnoRuntime.queryInterface(XTextContent.class, named); + } - if (parts.length >= 3 && parts[0].startsWith("JABREF_") && parts[1].startsWith("CID_")) { - this.citationKey = parts[0].substring(7); - this.citationNumber = parts[1].substring(4); - this.uniqueId = parts[2]; - System.out.println(citationKey); - System.out.println(citationNumber); - System.out.println(uniqueId); - } + public static CSLReferenceMark of(String citationKey, Integer citationNumber, XMultiServiceFactory factory) throws Exception { + String uniqueId = CUID.randomCUID2(8).toString(); + String name = "JABREF_" + citationKey + " CID_" + citationNumber + " " + uniqueId; + XNamed named = UnoRuntime.queryInterface(XNamed.class, factory.createInstance("com.sun.star.text.ReferenceMark")); + named.setName(name); + return new CSLReferenceMark(named, name, citationKey, citationNumber, uniqueId); } - public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception { + public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception, CreationException { XTextRange startRange = cursor.getStart(); OOTextIntoOO.write(doc, cursor, ooText); XTextRange endRange = cursor.getEnd(); @@ -44,23 +55,11 @@ public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText cursor.gotoRange(endRange, false); } - public String getName() { - return name; - } - public XTextContent getTextContent() { return textContent; } - public String getCitationKey() { - return citationKey; - } - - public String getCitationNumber() { - return citationNumber; - } - - public String getUniqueId() { - return uniqueId; + public String getName() { + return referenceMark.getName(); } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index 899b3160f5b..3ea1cc81ebe 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -4,10 +4,9 @@ import java.util.HashMap; import java.util.IdentityHashMap; import java.util.Map; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.Optional; +import org.jabref.logic.openoffice.ReferenceMark; import org.jabref.model.entry.BibEntry; import com.sun.star.container.XNameAccess; @@ -16,8 +15,13 @@ import com.sun.star.text.XReferenceMarksSupplier; import com.sun.star.text.XTextDocument; import com.sun.star.uno.UnoRuntime; +import io.github.thibaultmeyer.cuid.CUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class CSLReferenceMarkManager { + private static final Logger LOGGER = LoggerFactory.getLogger(CSLReferenceMarkManager.class); + private final HashMap marksByName; private final ArrayList marksByID; private final IdentityHashMap idsByMark; @@ -44,43 +48,24 @@ public void readExistingMarks() throws Exception { int citationCounter = 0; for (String name : marks.getElementNames()) { - String citationKey = extractCitationKey(name); - if (!citationKey.isEmpty()) { - citationOrder.putIfAbsent(citationKey, ++citationCounter); - + Optional referenceMark = ReferenceMark.of(name); + if (!referenceMark.isEmpty()) { + citationOrder.putIfAbsent(referenceMark.map(ReferenceMark::getCitationKey).get(), ++citationCounter); XNamed named = UnoRuntime.queryInterface(XNamed.class, marks.getByName(name)); - CSLReferenceMark mark = new CSLReferenceMark(named, name); + CSLReferenceMark mark = new CSLReferenceMark(named, referenceMark.get()); addMark(mark); } } } - private String extractCitationKey(String name) { - for (String prefix : CSLCitationOOAdapter.PREFIXES) { - if (name.startsWith(prefix)) { - String withoutPrefix = name.substring(prefix.length()); - String[] parts = withoutPrefix.split("\\s+"); - if (parts.length > 0) { - String key = parts[0]; - key = key.replaceAll("^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$", ""); - if (!key.isEmpty()) { - return key; - } - } - break; - } - } - return ""; - } - private void updateCitationInfo(String name) { - Pattern pattern = Pattern.compile("JABREF_(.+) CID_(\\d+) (.+)"); // Updated pattern - Matcher matcher = pattern.matcher(name); - if (matcher.find()) { - String citationKey = matcher.group(1); - int citationNumber = Integer.parseInt(matcher.group(2)); - citationKeyToNumber.put(citationKey, citationNumber); + Optional referenceMark = ReferenceMark.of(name); + if (referenceMark.isPresent()) { + int citationNumber = referenceMark.get().getCitationNumber(); + citationKeyToNumber.put(referenceMark.get().getCitationKey(), citationNumber); highestCitationNumber = Math.max(highestCitationNumber, citationNumber); + } else { + LOGGER.warn("Could not parse ReferenceMark name: {}", name); } } @@ -96,18 +81,10 @@ public int getCitationNumber(String citationKey) { } public CSLReferenceMark createReferenceMark(BibEntry entry) throws Exception { - String citationKey = entry.getCitationKey().orElse(""); + String citationKey = entry.getCitationKey().orElse(CUID.randomCUID2(8).toString()); int citationNumber = getCitationNumber(citationKey); - String uniqueId = UUID.randomUUID().toString().substring(0, 8); // Generate a unique ID - - String name = CSLCitationOOAdapter.PREFIXES[0] + citationKey + " CID_" + citationNumber + " " + uniqueId; - Object mark = factory.createInstance("com.sun.star.text.ReferenceMark"); - XNamed named = UnoRuntime.queryInterface(XNamed.class, mark); - named.setName(name); - - CSLReferenceMark referenceMark = new CSLReferenceMark(named, name); + CSLReferenceMark referenceMark = CSLReferenceMark.of(citationKey, citationNumber, factory); addMark(referenceMark); - return referenceMark; } diff --git a/src/test/java/org/jabref/logic/openoffice/ReferenceMarkTest.java b/src/test/java/org/jabref/logic/openoffice/ReferenceMarkTest.java new file mode 100644 index 00000000000..c6a95b1f6d3 --- /dev/null +++ b/src/test/java/org/jabref/logic/openoffice/ReferenceMarkTest.java @@ -0,0 +1,32 @@ +package org.jabref.logic.openoffice; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ReferenceMarkTest { + + @ParameterizedTest + @MethodSource + @DisplayName("Test parsing of valid reference marks") + void validParsing(String name, String expectedCitationKey, String expectedCitationNumber, String expectedUniqueId) { + ReferenceMark referenceMark = new ReferenceMark(name); + + assertEquals(expectedCitationKey, referenceMark.getCitationKey()); + assertEquals(expectedCitationNumber, referenceMark.getCitationNumber()); + assertEquals(expectedUniqueId, referenceMark.getUniqueId()); + } + + private static Stream validParsing() { + return Stream.of( + Arguments.of("JABREF_key1 CID_12345 uniqueId1", "key1", "12345", "uniqueId1"), + Arguments.of("JABREF_key2 CID_67890 uniqueId2", "key2", "67890", "uniqueId2"), + Arguments.of("JABREF_key3 CID_54321 uniqueId3", "key3", "54321", "uniqueId3") + ); + } +} From df9d68049ee668138b38c3fd177894de3d315dcd Mon Sep 17 00:00:00 2001 From: subhramit Date: Wed, 7 Aug 2024 03:37:56 +0530 Subject: [PATCH 36/94] YAY REFRESH BIBLIOGRAPHY --- .../org/jabref/gui/openoffice/OOBibBase.java | 60 +++++---- .../oocsltext/CSLCitationOOAdapter.java | 4 + .../oocsltext/CSLUpdateBibliography.java | 122 ++++++++++++++++++ 3 files changed, 158 insertions(+), 28 deletions(-) create mode 100644 src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 1eedce6b364..138ef04c9f0 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -23,6 +23,7 @@ import org.jabref.logic.openoffice.frontend.OOFrontend; import org.jabref.logic.openoffice.frontend.RangeForOverlapCheck; import org.jabref.logic.openoffice.oocsltext.CSLCitationOOAdapter; +import org.jabref.logic.openoffice.oocsltext.CSLUpdateBibliography; import org.jabref.logic.openoffice.style.JStyle; import org.jabref.logic.openoffice.style.OOStyle; import org.jabref.model.database.BibDatabase; @@ -47,15 +48,12 @@ import com.sun.star.beans.IllegalTypeException; import com.sun.star.beans.NotRemoveableException; import com.sun.star.beans.PropertyVetoException; -import com.sun.star.beans.XPropertySet; import com.sun.star.comp.helper.BootstrapException; import com.sun.star.container.NoSuchElementException; import com.sun.star.lang.DisposedException; import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; -import com.sun.star.text.XTextRange; -import com.sun.star.uno.UnoRuntime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -936,31 +934,37 @@ public void guiActionUpdateDocument(List databases, OOStyle style) return; } - // Create a new cursor at the end of the document for bibliography insertion - XTextCursor bibliographyCursor = doc.getText().createTextCursor(); - bibliographyCursor.gotoEnd(false); - - // Insert bibliography title - String bibliographyTitle = Localization.lang("\nReferences"); - bibliographyCursor.setString("\n"); - - // Apply formatting to the title (here, we make it bold and larger) - XTextRange titleRange = bibliographyCursor.getStart(); - titleRange.setString(bibliographyTitle); - XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); - titleProps.setPropertyValue("CharWeight", com.sun.star.awt.FontWeight.BOLD); - titleProps.setPropertyValue("CharHeight", 16f); - - // Move cursor to prevent reference mark bleed-out (current implementation) TODO: Remove once bleed-out is fixed - bibliographyCursor.goRight((short) 1, false); - - // Insert bibliography entries - // BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(databases.getFirst()); - // TODO: Ask Chris if injecting database context is a good idea - BibDatabaseContext bibDatabaseContext = Injector.instantiateModelOrService(BibDatabaseContext.class); - BibEntryTypesManager bibEntryTypesManager = Injector.instantiateModelOrService(BibEntryTypesManager.class); - - adapter.insertBibliography(bibliographyCursor, citationStyle, citedEntries, bibDatabaseContext, bibEntryTypesManager); + // A separate database and database + BibDatabase bibDatabase = new BibDatabase(citedEntries); + BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(bibDatabase); + + CSLUpdateBibliography.rebuildCSLBibliography(doc, adapter, citedEntries, citationStyle, Injector.instantiateModelOrService(BibDatabaseContext.class), Injector.instantiateModelOrService(BibEntryTypesManager.class)); + +// // Create a new cursor at the end of the document for bibliography insertion +// XTextCursor bibliographyCursor = doc.getText().createTextCursor(); +// bibliographyCursor.gotoEnd(false); +// +// // Insert bibliography title +// String bibliographyTitle = Localization.lang("\nReferences"); +// bibliographyCursor.setString("\n"); +// +// // Apply formatting to the title (here, we make it bold and larger) +// XTextRange titleRange = bibliographyCursor.getStart(); +// titleRange.setString(bibliographyTitle); +// XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); +// titleProps.setPropertyValue("CharWeight", com.sun.star.awt.FontWeight.BOLD); +// titleProps.setPropertyValue("CharHeight", 16f); +// +// // Move cursor to prevent reference mark bleed-out (current implementation) TODO: Remove once bleed-out is fixed +// bibliographyCursor.goRight((short) 1, false); +// +// // Insert bibliography entries +// // BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(databases.getFirst()); +// // TODO: Ask Chris if injecting database context is a good idea +// BibDatabaseContext bibDatabaseContext = Injector.instantiateModelOrService(BibDatabaseContext.class); +// BibEntryTypesManager bibEntryTypesManager = Injector.instantiateModelOrService(BibEntryTypesManager.class); +// +// adapter.insertBibliography(bibliographyCursor, citationStyle, citedEntries, bibDatabaseContext, bibEntryTypesManager); } finally { UnoUndo.leaveUndoContext(doc); fcursor.get().restore(doc); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index c476cd2200c..ba0e42042b0 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -47,6 +47,7 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); for (BibEntry entry: entries) { String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); + System.out.println(citation); writeCitation(document, cursor, entry, citation); } // List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); @@ -197,6 +198,9 @@ private String transformHtml(String html) { // Replace span tags with inline styles for italic html = html.replaceAll("(.*?)", "$1"); + // Replace span tags with inline styles for underline + // html = html.replaceAll("(.*?)", "$1"); + html = html.replaceAll("(.*?)", "$1"); // Clean up any remaining span tags diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java new file mode 100644 index 00000000000..f3a3e18180c --- /dev/null +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java @@ -0,0 +1,122 @@ +package org.jabref.logic.openoffice.oocsltext; + +import java.util.List; +import java.util.Optional; +import java.util.logging.Logger; + +import org.jabref.logic.citationstyle.CitationStyle; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibEntryTypesManager; +import org.jabref.model.openoffice.DocumentAnnotation; +import org.jabref.model.openoffice.uno.CreationException; +import org.jabref.model.openoffice.uno.NoDocumentException; +import org.jabref.model.openoffice.uno.UnoTextSection; + +import com.sun.star.lang.WrappedTargetException; +import com.sun.star.text.XTextCursor; +import com.sun.star.text.XTextDocument; +import com.sun.star.text.XTextRange; + +public class CSLUpdateBibliography { + + private static final String CSL_BIB_SECTION_NAME = "CSL_bibliography"; + private static final Logger LOGGER = Logger.getLogger(CSLUpdateBibliography.class.getName()); + + private CSLUpdateBibliography() { + } + + public static Optional getBibliographyRange(XTextDocument doc) + throws NoDocumentException, WrappedTargetException { + LOGGER.info("Attempting to get bibliography range"); + Optional range = UnoTextSection.getAnchor(doc, CSL_BIB_SECTION_NAME); + LOGGER.info("Bibliography range found: " + range.isPresent()); + return range; + } + + /** + * Rebuilds the bibliography using CSL. + */ + public static void rebuildCSLBibliography(XTextDocument doc, + CSLCitationOOAdapter cslAdapter, + List entries, + CitationStyle citationStyle, + BibDatabaseContext bibDatabaseContext, + BibEntryTypesManager bibEntryTypesManager) + throws Exception { + LOGGER.info("Starting to rebuild CSL bibliography"); + + // Ensure the bibliography section exists + Optional sectionRange = getBibliographyRange(doc); + if (sectionRange.isEmpty()) { + LOGGER.info("Bibliography section not found. Creating new section."); + createCSLBibTextSection(doc); + } else { + LOGGER.info("Bibliography section found. Clearing content."); + clearCSLBibTextSectionContent(doc); + } + + populateCSLBibTextSection(doc, cslAdapter, entries, citationStyle, bibDatabaseContext, bibEntryTypesManager); + LOGGER.info("Finished rebuilding CSL bibliography"); + } + + private static void createCSLBibTextSection(XTextDocument doc) + throws CreationException { + LOGGER.info("Creating new CSL bibliography section"); + XTextCursor textCursor = doc.getText().createTextCursor(); + textCursor.gotoEnd(false); + DocumentAnnotation annotation = new DocumentAnnotation(doc, CSL_BIB_SECTION_NAME, textCursor, false); + UnoTextSection.create(annotation); + LOGGER.info("CSL bibliography section created"); + } + + private static void clearCSLBibTextSectionContent(XTextDocument doc) + throws NoDocumentException, WrappedTargetException { + LOGGER.info("Clearing CSL bibliography section content"); + Optional sectionRange = getBibliographyRange(doc); + if (sectionRange.isPresent()) { + XTextCursor cursor = doc.getText().createTextCursorByRange(sectionRange.get()); + cursor.setString(""); + LOGGER.info("CSL bibliography section content cleared"); + } else { + LOGGER.warning("Failed to clear CSL bibliography section: section not found"); + } + } + + private static void populateCSLBibTextSection(XTextDocument doc, + CSLCitationOOAdapter cslAdapter, + List entries, + CitationStyle citationStyle, + BibDatabaseContext bibDatabaseContext, + BibEntryTypesManager bibEntryTypesManager) + throws Exception { + LOGGER.info("Populating CSL bibliography section"); + + Optional sectionRange = getBibliographyRange(doc); + if (sectionRange.isEmpty()) { + LOGGER.severe("Bibliography section not found when trying to populate"); + throw new IllegalStateException("Bibliography section not found"); + } + + XTextCursor cursor = doc.getText().createTextCursorByRange(sectionRange.get()); + + // Use CSLCitationOOAdapter to insert the bibliography + cslAdapter.insertBibliography(cursor, citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + LOGGER.info("Bibliography inserted using CSLCitationOOAdapter"); + + // Remove the initial empty paragraph from the section + sectionRange = getBibliographyRange(doc); + if (sectionRange.isPresent()) { + XTextCursor initialParagraph = doc.getText().createTextCursorByRange(sectionRange.get()); + initialParagraph.collapseToStart(); + initialParagraph.goRight((short) 1, true); + initialParagraph.setString(""); + LOGGER.info("Initial empty paragraph removed from bibliography section"); + } else { + LOGGER.warning("Failed to remove initial empty paragraph: bibliography section not found"); + } + + cursor.collapseToEnd(); + LOGGER.info("CSL bibliography section population completed"); + } +} From 898fcd08f439c9538a0e2d8edeb836c6570c7edb Mon Sep 17 00:00:00 2001 From: subhramit Date: Wed, 7 Aug 2024 05:55:20 +0530 Subject: [PATCH 37/94] Drastic improvements in CSL Reference Marks --- .../backend/NamedRangeReferenceMark.java | 4 +- .../oocsltext/CSLCitationOOAdapter.java | 21 +++++---- .../oocsltext/CSLReferenceMark.java | 47 ++++++++++++++++++- 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/backend/NamedRangeReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/backend/NamedRangeReferenceMark.java index 2c8fe7ae470..e2f0beb3cd2 100644 --- a/src/main/java/org/jabref/logic/openoffice/backend/NamedRangeReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/backend/NamedRangeReferenceMark.java @@ -18,7 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class NamedRangeReferenceMark implements NamedRange { +public class NamedRangeReferenceMark implements NamedRange { private static final String ZERO_WIDTH_SPACE = "\u200b"; @@ -58,7 +58,7 @@ String getId() { * @param numSpaces Number of spaces to insert. * @return a new cursor, covering the just-inserted spaces. */ - private static XTextCursor safeInsertSpacesBetweenReferenceMarks(XTextRange position, int numSpaces) { + public static XTextCursor safeInsertSpacesBetweenReferenceMarks(XTextRange position, int numSpaces) { // Start with an empty cursor at position.getStart(); XText text = position.getText(); XTextCursor cursor = text.createTextCursorByRange(position.getStart()); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index ba0e42042b0..19d64b278bb 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -84,14 +84,19 @@ public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List entries, OOText ooText) throws Exception { - // Insert the entire citation text as-is - OOTextIntoOO.write(doc, cursor, ooText); - // Insert reference marks for each entry after the citation - for (BibEntry entry : entries) { - CSLReferenceMark mark = markManager.createReferenceMark(entry); - OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); - mark.insertReferenceIntoOO(doc, cursor, emptyOOText); + if (entries.size() == 1) { + CSLReferenceMark mark = markManager.createReferenceMark(entries.getFirst()); + mark.insertReferenceIntoOO(doc, cursor, ooText, true, true, true); + } else { + cursor.getText().insertString(cursor, " ", false); + OOTextIntoOO.write(doc, cursor, ooText); + for (BibEntry entry : entries) { + CSLReferenceMark mark = markManager.createReferenceMark(entry); + OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); + mark.insertReferenceIntoOO(doc, cursor, emptyOOText, false, false, true); + } + cursor.getText().insertString(cursor, " ", false); } // Move the cursor to the end of the inserted text @@ -131,7 +136,7 @@ private void writeCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); // Insert the citation text wrapped in a reference mark - mark.insertReferenceIntoOO(doc, cursor, ooText); + mark.insertReferenceIntoOO(doc, cursor, ooText, false, false, true); // Move the cursor to the end of the inserted text cursor.collapseToEnd(); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index 3927a0033b6..da6265fce42 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -1,9 +1,11 @@ package org.jabref.logic.openoffice.oocsltext; import org.jabref.logic.openoffice.ReferenceMark; +import org.jabref.model.openoffice.DocumentAnnotation; import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; import org.jabref.model.openoffice.uno.CreationException; +import org.jabref.model.openoffice.uno.UnoReferenceMark; import com.sun.star.container.XNamed; import com.sun.star.lang.XMultiServiceFactory; @@ -17,6 +19,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.jabref.logic.openoffice.backend.NamedRangeReferenceMark.safeInsertSpacesBetweenReferenceMarks; + /** * Class to handle a reference mark. See {@link CSLReferenceMarkManager} for the management of all reference marks. */ @@ -45,14 +49,53 @@ public static CSLReferenceMark of(String citationKey, Integer citationNumber, XM return new CSLReferenceMark(named, name, citationKey, citationNumber, uniqueId); } - public void insertReferenceIntoOO(XTextDocument doc, XTextCursor cursor, OOText ooText) throws Exception, CreationException { + public void insertReferenceIntoOO(XTextDocument doc, XTextCursor position, OOText ooText, boolean insertSpaceBefore, boolean insertSpaceAfter, boolean withoutBrackets) throws Exception, CreationException { + // Ensure the cursor is at the end of its range + position.collapseToEnd(); + + // Insert spaces safely + XTextCursor cursor = safeInsertSpacesBetweenReferenceMarks(position.getEnd(), 2); + + // Cursors before the first and after the last space + XTextCursor cursorBefore = cursor.getText().createTextCursorByRange(cursor.getStart()); + XTextCursor cursorAfter = cursor.getText().createTextCursorByRange(cursor.getEnd()); + + cursor.collapseToStart(); + cursor.goRight((short) 1, false); + // Now we are between two spaces + + // Store the start position XTextRange startRange = cursor.getStart(); + + // Insert the OOText content OOTextIntoOO.write(doc, cursor, ooText); + + // Store the end position XTextRange endRange = cursor.getEnd(); + + // Move cursor to wrap the entire inserted content cursor.gotoRange(startRange, false); cursor.gotoRange(endRange, true); - textContent.attach(cursor); + + // Create DocumentAnnotation and attach it + DocumentAnnotation documentAnnotation = new DocumentAnnotation(doc, referenceMark.getName(), cursor, true); + UnoReferenceMark.create(documentAnnotation); + + // Move cursor to the end of the inserted content cursor.gotoRange(endRange, false); + + // Remove extra spaces + if (!insertSpaceBefore) { + cursorBefore.goRight((short) 1, true); + cursorBefore.setString(""); + } + if (!insertSpaceAfter) { + cursorAfter.goLeft((short) 1, true); + cursorAfter.setString(""); + } + + // Move the original position cursor to the end of the inserted content + position.gotoRange(cursorAfter.getEnd(), false); } public XTextContent getTextContent() { From 3c3d7a7c6fc4c13f4dc7066f1d20177616f65de2 Mon Sep 17 00:00:00 2001 From: subhramit Date: Wed, 7 Aug 2024 06:53:53 +0530 Subject: [PATCH 38/94] Fix extra newline in numeric styles --- .../org/jabref/gui/openoffice/OOBibBase.java | 2 +- .../oocsltext/CSLCitationOOAdapter.java | 8 ++++++++ .../oocsltext/CSLUpdateBibliography.java | 20 +++++++++---------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 138ef04c9f0..100dbb9b428 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -938,7 +938,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) BibDatabase bibDatabase = new BibDatabase(citedEntries); BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(bibDatabase); - CSLUpdateBibliography.rebuildCSLBibliography(doc, adapter, citedEntries, citationStyle, Injector.instantiateModelOrService(BibDatabaseContext.class), Injector.instantiateModelOrService(BibEntryTypesManager.class)); + CSLUpdateBibliography.rebuildCSLBibliography(doc, adapter, citedEntries, citationStyle, bibDatabaseContext, Injector.instantiateModelOrService(BibEntryTypesManager.class)); // // Create a new cursor at the end of the document for bibliography insertion // XTextCursor bibliographyCursor = doc.getText().createTextCursor(); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 19d64b278bb..dd6fa5e44a0 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -49,6 +49,14 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); System.out.println(citation); writeCitation(document, cursor, entry, citation); + + if (isNumericStyle) { + // Select the paragraph break + cursor.goLeft((short) 1, true); + + // Delete the selected content (paragraph break) + cursor.setString(""); + } } // List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java index f3a3e18180c..736bb78ec91 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java @@ -105,16 +105,16 @@ private static void populateCSLBibTextSection(XTextDocument doc, LOGGER.info("Bibliography inserted using CSLCitationOOAdapter"); // Remove the initial empty paragraph from the section - sectionRange = getBibliographyRange(doc); - if (sectionRange.isPresent()) { - XTextCursor initialParagraph = doc.getText().createTextCursorByRange(sectionRange.get()); - initialParagraph.collapseToStart(); - initialParagraph.goRight((short) 1, true); - initialParagraph.setString(""); - LOGGER.info("Initial empty paragraph removed from bibliography section"); - } else { - LOGGER.warning("Failed to remove initial empty paragraph: bibliography section not found"); - } +// sectionRange = getBibliographyRange(doc); +// if (sectionRange.isPresent()) { +// XTextCursor initialParagraph = doc.getText().createTextCursorByRange(sectionRange.get()); +// initialParagraph.collapseToStart(); +// initialParagraph.goRight((short) 1, true); +// initialParagraph.setString(""); +// LOGGER.info("Initial empty paragraph removed from bibliography section"); +// } else { +// LOGGER.warning("Failed to remove initial empty paragraph: bibliography section not found"); +// } cursor.collapseToEnd(); LOGGER.info("CSL bibliography section population completed"); From a347ab8eca1d67f5210603c14d82ee7e328444c6 Mon Sep 17 00:00:00 2001 From: subhramit Date: Wed, 7 Aug 2024 07:03:41 +0530 Subject: [PATCH 39/94] fix helpertext --- .../java/org/jabref/gui/openoffice/OpenOfficePanel.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index 6695cdb76a5..8ed634fd3c7 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -230,11 +230,7 @@ private void initPanel() { pushEntriesAdvanced.setOnAction(e -> pushEntries(CitationType.AUTHORYEAR_INTEXT, true)); pushEntriesAdvanced.setMaxWidth(Double.MAX_VALUE); - if (currentStyle instanceof CitationStyle) { - update.setTooltip(new Tooltip(Localization.lang("Make bibliography"))); - } else if (currentStyle instanceof JStyle) { - update.setTooltip(new Tooltip(Localization.lang("Make or update the bibliography"))); - } + update.setTooltip(new Tooltip(Localization.lang("Make/Update bibliography"))); update.setOnAction(event -> { String title = Localization.lang("Could not update bibliography"); From d0a329ff8f9ba5577503c6ec77f6231c80a1098d Mon Sep 17 00:00:00 2001 From: subhramit Date: Wed, 7 Aug 2024 07:14:10 +0530 Subject: [PATCH 40/94] Add support for CSL styles with underline --- .../jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index dd6fa5e44a0..f87d1d372fc 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -212,7 +212,7 @@ private String transformHtml(String html) { html = html.replaceAll("(.*?)", "$1"); // Replace span tags with inline styles for underline - // html = html.replaceAll("(.*?)", "$1"); + html = html.replaceAll("(.*?)", "$1"); html = html.replaceAll("(.*?)", "$1"); From aa258258731dac21d1f6edf3cc93f0a7c068da23 Mon Sep 17 00:00:00 2001 From: subhramit Date: Wed, 7 Aug 2024 19:49:53 +0530 Subject: [PATCH 41/94] Move current cite in-text functionality to Cite button, disable Cite in-text button --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 7 +++++-- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 100dbb9b428..022c10dd432 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -615,9 +615,12 @@ public void guiActionInsertEntry(List entries, adapter.readExistingMarks(); if (citationType == CitationType.AUTHORYEAR_INTEXT) { - adapter.insertInText(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + // TODO: "Cite in-text button" - For olly + // Below was what we did initially, no utility, hence button non-functional till replaced by todo changes + // adapter.insertBibliography(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } else { - adapter.insertBibliography(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + // "Cite" button + adapter.insertInText(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } } else if (style instanceof JStyle jStyle) { // Handle insertion of JStyle citations diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index f87d1d372fc..5a5da2cb8d6 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -73,7 +73,7 @@ public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List Date: Wed, 7 Aug 2024 20:07:10 +0530 Subject: [PATCH 42/94] Smart spaces --- .../oocsltext/CSLCitationOOAdapter.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 5a5da2cb8d6..01737aaef74 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -92,12 +92,29 @@ public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List entries, OOText ooText) throws Exception { - // Insert reference marks for each entry after the citation + // Check if there's already a space before the cursor + boolean spaceExists = false; + XTextCursor checkCursor = cursor.getText().createTextCursorByRange(cursor.getStart()); + + // Check if we're at the start of the document or if there's a space before + if (!checkCursor.goLeft((short) 1, true)) { + // We're at the start of the document + spaceExists = true; + } else { + spaceExists = checkCursor.getString().equals(" "); + // If not a space, check if it's a paragraph break + if (!spaceExists) { + spaceExists = checkCursor.getString().matches("\\R"); + } + } + if (entries.size() == 1) { CSLReferenceMark mark = markManager.createReferenceMark(entries.getFirst()); - mark.insertReferenceIntoOO(doc, cursor, ooText, true, true, true); + mark.insertReferenceIntoOO(doc, cursor, ooText, !spaceExists, true, true); } else { - cursor.getText().insertString(cursor, " ", false); + if (!spaceExists) { + cursor.getText().insertString(cursor, " ", false); + } OOTextIntoOO.write(doc, cursor, ooText); for (BibEntry entry : entries) { CSLReferenceMark mark = markManager.createReferenceMark(entry); From fc156ccb2589fdb38c194ca51a1bc2232b897435 Mon Sep 17 00:00:00 2001 From: subhramit Date: Wed, 7 Aug 2024 20:13:48 +0530 Subject: [PATCH 43/94] Better comments for samrt spaces --- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 01737aaef74..d862b5f97eb 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -96,11 +96,12 @@ private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, boolean spaceExists = false; XTextCursor checkCursor = cursor.getText().createTextCursorByRange(cursor.getStart()); - // Check if we're at the start of the document or if there's a space before + // Check if we're at the start of the document - if yes we set the flag and don't insert a space if (!checkCursor.goLeft((short) 1, true)) { // We're at the start of the document spaceExists = true; } else { + // If not at the start of document, check if there's a space before spaceExists = checkCursor.getString().equals(" "); // If not a space, check if it's a paragraph break if (!spaceExists) { From ad6730068c1ad7d5013cd787f87e3674f65bf6f2 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Wed, 7 Aug 2024 20:17:25 +0200 Subject: [PATCH 44/94] Use Java Iterator --- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index d862b5f97eb..57997bfd40e 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,6 +1,7 @@ package org.jabref.logic.openoffice.oocsltext; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -133,16 +134,15 @@ private String updateMultipleCitations(String citation, List entries) Pattern pattern = Pattern.compile("(\\D*)(\\d+)(\\D*)"); Matcher matcher = pattern.matcher(citation); StringBuilder sb = new StringBuilder(); - int entryIndex = 0; + Iterator iterator = entries.iterator(); - while (matcher.find() && entryIndex < entries.size()) { + while (matcher.find() && iterator.hasNext()) { String prefix = matcher.group(1); String suffix = matcher.group(3); - int currentNumber = markManager.getCitationNumber(entries.get(entryIndex).getCitationKey().orElse("")); + int currentNumber = markManager.getCitationNumber(iterator.next().getCitationKey().orElse("")); matcher.appendReplacement(sb, Matcher.quoteReplacement(prefix + currentNumber + suffix)); - entryIndex++; } matcher.appendTail(sb); return sb.toString(); From 954796394b706e8efd6a6d7496a198ba3b1101c6 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Wed, 7 Aug 2024 20:17:41 +0200 Subject: [PATCH 45/94] IntelliJ formatting --- .../jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 57997bfd40e..e1469477564 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -46,7 +46,7 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, // Sort entries based on their order of appearance in the document entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); - for (BibEntry entry: entries) { + for (BibEntry entry : entries) { String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); System.out.println(citation); writeCitation(document, cursor, entry, citation); From 689b43a71741f76194de58867a6f40e0622ffb14 Mon Sep 17 00:00:00 2001 From: subhramit Date: Thu, 8 Aug 2024 00:28:30 +0530 Subject: [PATCH 46/94] Change sync bibliography icon --- .../java/org/jabref/gui/icon/IconTheme.java | 3 ++- .../gui/icon/JabRefMaterialDesignIcon.java | 3 ++- .../gui/openoffice/OpenOfficePanel.java | 4 ++-- .../resources/fonts/JabRefMaterialDesign.ttf | Bin 8604 -> 8756 bytes 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/icon/IconTheme.java b/src/main/java/org/jabref/gui/icon/IconTheme.java index 566c62c1f32..ab3aaf6cdf6 100644 --- a/src/main/java/org/jabref/gui/icon/IconTheme.java +++ b/src/main/java/org/jabref/gui/icon/IconTheme.java @@ -359,7 +359,8 @@ public enum JabRefIcons implements JabRefIcon { REMOVE_TAGS(MaterialDesignC.CLOSE), ACCEPT_LEFT(MaterialDesignS.SUBDIRECTORY_ARROW_LEFT), ACCEPT_RIGHT(MaterialDesignS.SUBDIRECTORY_ARROW_RIGHT), - MERGE_GROUPS(MaterialDesignS.SOURCE_MERGE); + MERGE_GROUPS(MaterialDesignS.SOURCE_MERGE), + ADD_OR_MAKE_BIBLIOGRAPHY(JabRefMaterialDesignIcon.BIBLIOGRAPHY); private final JabRefIcon icon; JabRefIcons(Ikon... icons) { diff --git a/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java b/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java index 5d8deaa5d91..3dd28d6d242 100644 --- a/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java +++ b/src/main/java/org/jabref/gui/icon/JabRefMaterialDesignIcon.java @@ -32,7 +32,8 @@ public enum JabRefMaterialDesignIcon implements Ikon { CANCEL("jab-cancel", '\ue90e'), SUBLIME_TEXT("jab-sublime-text", '\ue90f'), TEXSHOP("jab-texshop", '\ue910'), - TEXWORKS("jab-texworks", '\ue911'); + TEXWORKS("jab-texworks", '\ue911'), + BIBLIOGRAPHY("jab-bibliography", '\ue912'); private String description; private int code; diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index 8ed634fd3c7..fbd09aacad5 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -144,7 +144,7 @@ public OpenOfficePanel(LibraryTabContainer tabContainer, selectDocument.setMaxWidth(Double.MAX_VALUE); update = new Button(); - update.setGraphic(IconTheme.JabRefIcons.REFRESH.getGraphicNode()); + update.setGraphic(IconTheme.JabRefIcons.ADD_OR_MAKE_BIBLIOGRAPHY.getGraphicNode()); update.setTooltip(new Tooltip(Localization.lang("Sync OpenOffice/LibreOffice bibliography"))); update.setMaxWidth(Double.MAX_VALUE); @@ -230,7 +230,7 @@ private void initPanel() { pushEntriesAdvanced.setOnAction(e -> pushEntries(CitationType.AUTHORYEAR_INTEXT, true)); pushEntriesAdvanced.setMaxWidth(Double.MAX_VALUE); - update.setTooltip(new Tooltip(Localization.lang("Make/Update bibliography"))); + update.setTooltip(new Tooltip(Localization.lang("Make/Sync bibliography"))); update.setOnAction(event -> { String title = Localization.lang("Could not update bibliography"); diff --git a/src/main/resources/fonts/JabRefMaterialDesign.ttf b/src/main/resources/fonts/JabRefMaterialDesign.ttf index 21525c7a697f89e507065bfd4625306f2cfe1fb5..fb5b40fb76b9c53a2bb08fe4b50539a98fade7e3 100644 GIT binary patch delta 457 zcmX|-JuE{}7>3`|dsXYFrCeR~_Rml`32o(K@DtHQf`s7S7z8&}D(Tf5HPqy;Y;+<9 zdkv%#9Sn`xASOlzF`?b56&vQhQ(k8eu^|d}h8k>Ge4yl-!V3 z(}r&PwTEMXbrLUZ=mnE%3$a~Y8@b)}%Y*%E;vx_*vl)FY_8?PBek1G8Qc!;@JOaTG zaaY#ZDbCS`I7POU%csZmg_ETu1!ok*4ZUb0$g0Hm#Gx(S$Sj|CKNG(Lj)<8r?9iaJ zBJFk`g7A7+8)d#DHpP6EY32^>If3t*UTTjVsU{mG<=+G(tKhd$6KQUJU>acIb38wG44k1cwCqOuYiWbV36kk3h3n~RunMEG425JEr5K5yu{qpxHZ}jf&2&t z1}3F~{NfUzLxDiC1|-kG%=~oX0eeQlNsQi%f}4F9Ic1eW{$XNZc*l8NKAzv^D+4zR zNIk Date: Wed, 7 Aug 2024 21:01:34 +0200 Subject: [PATCH 47/94] Add support for in-text citations --- .../org/jabref/gui/openoffice/OOBibBase.java | 10 ++- .../citationkeypattern/BracketedPattern.java | 4 +- .../oocsltext/CSLCitationOOAdapter.java | 66 ++++++++++++++----- .../java/org/jabref/model/entry/BibEntry.java | 2 + 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 022c10dd432..03a6a87bc9c 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -606,7 +606,6 @@ public void guiActionInsertEntry(List entries, } try { - UnoUndo.enterUndoContext(doc, "Insert citation"); if (style instanceof CitationStyle citationStyle) { // Handle insertion of CSL Style citations @@ -615,12 +614,11 @@ public void guiActionInsertEntry(List entries, adapter.readExistingMarks(); if (citationType == CitationType.AUTHORYEAR_INTEXT) { - // TODO: "Cite in-text button" - For olly - // Below was what we did initially, no utility, hence button non-functional till replaced by todo changes - // adapter.insertBibliography(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); - } else { // "Cite" button - adapter.insertInText(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + adapter.insertInTextCitation(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + } else { + // "Cite in text" button + adapter.insertCitation(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } } else if (style instanceof JStyle jStyle) { // Handle insertion of JStyle citations diff --git a/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java b/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java index 826361fa990..b1603a16651 100644 --- a/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java +++ b/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java @@ -874,7 +874,7 @@ static String authorsAlpha(AuthorList authorList) { List vonAndLastNames = authorList.getAuthors().stream() .limit(maxAuthors) .map(Author::getNamePrefixAndFamilyName) - .collect(Collectors.toList()); + .toList(); for (String vonAndLast : vonAndLastNames) { // replace all whitespaces by " " // split the lastname at " " @@ -902,7 +902,7 @@ static String authorsAlpha(AuthorList authorList) { * @return a string consisting of authors' last names separated by a `delimiter` and with any authors excess of * `maxAuthors` replaced with `suffix` */ - private static String joinAuthorsOnLastName(AuthorList authorList, int maxAuthors, String delimiter, final String suffix) { + public static String joinAuthorsOnLastName(AuthorList authorList, int maxAuthors, String delimiter, final String suffix) { final String finalSuffix = authorList.getNumberOfAuthors() > maxAuthors ? suffix : ""; return authorList.getAuthors().stream() .map(author -> { diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index e1469477564..7dfaa63b0cc 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -6,12 +6,15 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jabref.logic.citationkeypattern.BracketedPattern; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.logic.citationstyle.CitationStyleGenerator; import org.jabref.logic.citationstyle.CitationStyleOutputFormat; import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibEntryTypesManager; +import org.jabref.model.entry.field.StandardField; import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; @@ -68,9 +71,7 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, // } } - public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws Exception { - + public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); @@ -84,37 +85,66 @@ public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) + throws Exception { + String style = selectedStyle.getSource(); + isNumericStyle = selectedStyle.isNumericStyle(); + + Iterator iterator = entries.iterator(); + while (iterator.hasNext()) { + BibEntry currentEntry = iterator.next(); + String inTextCitation = CitationStyleGenerator.generateInText(List.of(currentEntry), style, format, bibDatabaseContext, bibEntryTypesManager).getText(); + String formattedCitation = transformHtml(inTextCitation); + if (isNumericStyle) { + formattedCitation = updateMultipleCitations(formattedCitation, List.of(currentEntry)); + } + String prefix = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) + .map(authors -> AuthorList.parse(authors)) + .map(list -> BracketedPattern.joinAuthorsOnLastName(list, 1, "", " et al.") + " ") + .orElse(""); + String finalText = prefix + formattedCitation; + if (iterator.hasNext()) { + finalText += ","; + // The next space is inserted somehow magically by other routines. Therefore, we do not add a space here. + } + OOText ooText = OOFormat.setLocaleNone(OOText.fromString(finalText)); + insertMultipleReferenceMarks(document, cursor, List.of(currentEntry), ooText); + cursor.collapseToEnd(); + } + } + private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, List entries, OOText ooText) throws Exception { - // Check if there's already a space before the cursor - boolean spaceExists = false; + boolean preceedingSpaceExists; XTextCursor checkCursor = cursor.getText().createTextCursorByRange(cursor.getStart()); // Check if we're at the start of the document - if yes we set the flag and don't insert a space if (!checkCursor.goLeft((short) 1, true)) { // We're at the start of the document - spaceExists = true; + preceedingSpaceExists = true; } else { - // If not at the start of document, check if there's a space before - spaceExists = checkCursor.getString().equals(" "); + // If not at the start of document, check if there is a space before + preceedingSpaceExists = checkCursor.getString().equals(" "); // If not a space, check if it's a paragraph break - if (!spaceExists) { - spaceExists = checkCursor.getString().matches("\\R"); + if (!preceedingSpaceExists) { + preceedingSpaceExists = checkCursor.getString().matches("\\R"); } } if (entries.size() == 1) { CSLReferenceMark mark = markManager.createReferenceMark(entries.getFirst()); - mark.insertReferenceIntoOO(doc, cursor, ooText, !spaceExists, true, true); + mark.insertReferenceIntoOO(doc, cursor, ooText, !preceedingSpaceExists, false, true); } else { - if (!spaceExists) { + if (!preceedingSpaceExists) { cursor.getText().insertString(cursor, " ", false); } OOTextIntoOO.write(doc, cursor, ooText); @@ -123,13 +153,15 @@ private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); mark.insertReferenceIntoOO(doc, cursor, emptyOOText, false, false, true); } - cursor.getText().insertString(cursor, " ", false); } // Move the cursor to the end of the inserted text cursor.collapseToEnd(); } + /** + * Transforms the numbers in the citation to globally-unique numbers + */ private String updateMultipleCitations(String citation, List entries) { Pattern pattern = Pattern.compile("(\\D*)(\\d+)(\\D*)"); Matcher matcher = pattern.matcher(citation); diff --git a/src/main/java/org/jabref/model/entry/BibEntry.java b/src/main/java/org/jabref/model/entry/BibEntry.java index 91fb8d01f51..e23c0268a43 100644 --- a/src/main/java/org/jabref/model/entry/BibEntry.java +++ b/src/main/java/org/jabref/model/entry/BibEntry.java @@ -722,6 +722,8 @@ public Object clone() { * to a) enable debugging the internal representation and b) save time at this method. *

* Serializes all fields, even the JabRef internal ones. Does NOT serialize "KEY_FIELD" as field, but as key. + *

+ * Alternative for some more readable output: {@link #getAuthorTitleYear(int)} */ @Override public String toString() { From 813fcb21cf3a6544e772b43d9f01020df4e79536 Mon Sep 17 00:00:00 2001 From: subhramit Date: Thu, 8 Aug 2024 01:20:30 +0530 Subject: [PATCH 48/94] Disable irrelevant buttons for CSL --- .../org/jabref/gui/openoffice/OpenOfficePanel.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index fbd09aacad5..e494967a462 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -214,6 +214,7 @@ private void initPanel() { } else if (currentStyle instanceof CitationStyle cslStyle) { dialogService.notify(Localization.lang("Currently selected CSL Style: '%0'", cslStyle.getName())); } + updateButtonAvailability(); }); }); @@ -390,12 +391,13 @@ private void updateButtonAvailability() { pushEntriesAdvanced.setDisable(!canCite); boolean canRefreshDocument = isConnectedToDocument && hasStyle; + boolean cslStyleSelected = preferencesService.getOpenOfficePreferences().getCurrentStyle() instanceof CitationStyle; update.setDisable(!canRefreshDocument); - merge.setDisable(!canRefreshDocument); - unmerge.setDisable(!canRefreshDocument); - manageCitations.setDisable(!canRefreshDocument); + merge.setDisable(!canRefreshDocument || cslStyleSelected); + unmerge.setDisable(!canRefreshDocument || cslStyleSelected); + manageCitations.setDisable(!canRefreshDocument || cslStyleSelected); - exportCitations.setDisable(!(isConnectedToDocument && hasDatabase)); + exportCitations.setDisable(!(isConnectedToDocument && hasDatabase) || cslStyleSelected); } private void connect() { From 63bb146db2c1ddb955d78bf4c940c8b1bfba0d41 Mon Sep 17 00:00:00 2001 From: subhramit Date: Thu, 8 Aug 2024 03:01:32 +0530 Subject: [PATCH 49/94] Implement insert empty citations, disable cite special, refactor --- .../org/jabref/gui/openoffice/OOBibBase.java | 11 ++++++---- .../gui/openoffice/OpenOfficePanel.java | 5 +++-- .../oocsltext/CSLCitationOOAdapter.java | 22 ++++++++++++++----- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 022c10dd432..9eeafd70ee6 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -614,13 +614,16 @@ public void guiActionInsertEntry(List entries, CSLCitationOOAdapter adapter = new CSLCitationOOAdapter(doc); adapter.readExistingMarks(); - if (citationType == CitationType.AUTHORYEAR_INTEXT) { + if (citationType == CitationType.AUTHORYEAR_PAR) { + // "Cite" button + adapter.insertInText(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + } else if (citationType == CitationType.AUTHORYEAR_INTEXT) { // TODO: "Cite in-text button" - For olly // Below was what we did initially, no utility, hence button non-functional till replaced by todo changes // adapter.insertBibliography(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); - } else { - // "Cite" button - adapter.insertInText(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + } else if (citationType == CitationType.INVISIBLE_CIT) { + // "Insert empty citation" + adapter.insertEmpty(cursor.get(), entries); } } else if (style instanceof JStyle jStyle) { // Handle insertion of JStyle citations diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index e494967a462..ebd67605480 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -386,12 +386,13 @@ private void updateButtonAvailability() { pushEntries.setDisable(!(isConnectedToDocument && hasStyle && hasDatabase)); boolean canCite = isConnectedToDocument && hasStyle && hasSelectedBibEntry; + boolean cslStyleSelected = preferencesService.getOpenOfficePreferences().getCurrentStyle() instanceof CitationStyle; pushEntriesInt.setDisable(!canCite); pushEntriesEmpty.setDisable(!canCite); - pushEntriesAdvanced.setDisable(!canCite); + pushEntriesAdvanced.setDisable(!canCite || cslStyleSelected); boolean canRefreshDocument = isConnectedToDocument && hasStyle; - boolean cslStyleSelected = preferencesService.getOpenOfficePreferences().getCurrentStyle() instanceof CitationStyle; + update.setDisable(!canRefreshDocument); merge.setDisable(!canRefreshDocument || cslStyleSelected); unmerge.setDisable(!canRefreshDocument || cslStyleSelected); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index d862b5f97eb..2440e82dbb2 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -85,13 +85,25 @@ public void insertInText(XTextCursor cursor, CitationStyle selectedStyle, List entries, OOText ooText) throws Exception { + public void insertEmpty(XTextCursor cursor, List entries) + throws Exception { + for (BibEntry entry : entries) { + CSLReferenceMark mark = markManager.createReferenceMark(entry); + OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); + mark.insertReferenceIntoOO(document, cursor, emptyOOText, false, false, true); + } + + // Move the cursor to the end of the inserted text - although no need as we don't insert any text, but a good practice + cursor.collapseToEnd(); + } + + private void insertMultipleReferenceMarks(XTextCursor cursor, List entries, OOText ooText) throws Exception { // Check if there's already a space before the cursor boolean spaceExists = false; XTextCursor checkCursor = cursor.getText().createTextCursorByRange(cursor.getStart()); @@ -111,16 +123,16 @@ private void insertMultipleReferenceMarks(XTextDocument doc, XTextCursor cursor, if (entries.size() == 1) { CSLReferenceMark mark = markManager.createReferenceMark(entries.getFirst()); - mark.insertReferenceIntoOO(doc, cursor, ooText, !spaceExists, true, true); + mark.insertReferenceIntoOO(document, cursor, ooText, !spaceExists, true, true); } else { if (!spaceExists) { cursor.getText().insertString(cursor, " ", false); } - OOTextIntoOO.write(doc, cursor, ooText); + OOTextIntoOO.write(document, cursor, ooText); for (BibEntry entry : entries) { CSLReferenceMark mark = markManager.createReferenceMark(entry); OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); - mark.insertReferenceIntoOO(doc, cursor, emptyOOText, false, false, true); + mark.insertReferenceIntoOO(document, cursor, emptyOOText, false, false, true); } cursor.getText().insertString(cursor, " ", false); } From f59ee52c8102fa44c997c2ceb743c8694df724b9 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 8 Aug 2024 08:54:58 +0200 Subject: [PATCH 50/94] Remove unused variable --- src/main/java/org/jabref/logic/openoffice/ReferenceMark.java | 5 ----- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 1 - 2 files changed, 6 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/ReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/ReferenceMark.java index b9f3fd449cd..87d2354da95 100644 --- a/src/main/java/org/jabref/logic/openoffice/ReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/ReferenceMark.java @@ -4,15 +4,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.jabref.logic.openoffice.oocsltext.CSLCitationOOAdapter; - import io.github.thibaultmeyer.cuid.CUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * See {@link CSLCitationOOAdapter#PREFIXES} for the prefix(es) used to identify reference marks. - */ public class ReferenceMark { private static final Logger LOGGER = LoggerFactory.getLogger(ReferenceMark.class); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index a955567b8ec..7ab2370ade0 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -25,7 +25,6 @@ public class CSLCitationOOAdapter { - public static final String[] PREFIXES = {"JABREF_", "CSL_"}; private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; From 6fdd792967e891c9c76bd807ef198d4a520b62ea Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 8 Aug 2024 09:07:37 +0200 Subject: [PATCH 51/94] Fix "cite in-text" --- .../openoffice/oocsltext/CSLCitationOOAdapter.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 7ab2370ade0..d6128e9ba01 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -25,6 +25,7 @@ public class CSLCitationOOAdapter { + private static final Pattern YEAR_IN_CITATION_PATTERN = Pattern.compile("(.).*?, (\\d{4}.*)"); private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; @@ -99,6 +100,8 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); + boolean twoEntries = entries.size() == 2; + Iterator iterator = entries.iterator(); while (iterator.hasNext()) { BibEntry currentEntry = iterator.next(); @@ -106,6 +109,8 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle String formattedCitation = transformHtml(inTextCitation); if (isNumericStyle) { formattedCitation = updateMultipleCitations(formattedCitation, List.of(currentEntry)); + } else { + formattedCitation = extractYear(formattedCitation); } String prefix = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) .map(authors -> AuthorList.parse(authors)) @@ -122,6 +127,14 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle } } + private String extractYear(String formattedCitation) { + Matcher matcher = YEAR_IN_CITATION_PATTERN.matcher(formattedCitation); + if (matcher.find()) { + return matcher.group(1) + matcher.group(2); + } + return formattedCitation; + } + public void insertEmpty(XTextCursor cursor, List entries) throws Exception { for (BibEntry entry : entries) { From e76fbafe9860819f5317ae680c3e27b2033d1013 Mon Sep 17 00:00:00 2001 From: subhramit Date: Thu, 8 Aug 2024 20:47:36 +0530 Subject: [PATCH 52/94] Bibliography title stage 1 --- .../oocsltext/CSLCitationOOAdapter.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index d6128e9ba01..10445844867 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -26,6 +26,10 @@ public class CSLCitationOOAdapter { private static final Pattern YEAR_IN_CITATION_PATTERN = Pattern.compile("(.).*?, (\\d{4}.*)"); + public static final String[] PREFIXES = {"JABREF_", "CSL_"}; + // TODO: These are static final fields right now, should add the functionality to let user select these and store them in preferences. + public static final String BIBLIOGRAPHY_TITLE = "References"; + public static final String BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT = "Heading 2"; private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; @@ -43,17 +47,32 @@ public void readExistingMarks() throws Exception { public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { +// XTextCursor bibliographyCursor = document.getText().createTextCursor(); +// bibliographyCursor.gotoEnd(false); +// XTextRange titleRange = bibliographyCursor.getStart(); +// titleRange.setString(BIBLIOGRAPHY_TITLE); +// XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); +// titleProps.setPropertyValue("ParaStyleName", BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); +// +// // Clear formatting after the title +// bibliographyCursor.gotoEnd(false); +// bibliographyCursor.goRight((short) 1, false); // Move to the start of the next paragraph +// XPropertySet paragraphProps = UnoRuntime.queryInterface(XPropertySet.class, bibliographyCursor); +// paragraphProps.setPropertyValue("ParaStyleName", "Default Paragraph Style"); // Or use your default style name + OOText title = OOFormat.paragraph(OOText.fromString(BIBLIOGRAPHY_TITLE), BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); + OOTextIntoOO.write(document, cursor, OOText.fromString(title.toString())); + OOText ooBreak = OOFormat.paragraph(OOText.fromString(""), "Body Text"); + OOTextIntoOO.write(document, cursor, ooBreak); String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); // Sort entries based on their order of appearance in the document entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); + for (BibEntry entry : entries) { String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); - System.out.println(citation); writeCitation(document, cursor, entry, citation); - if (isNumericStyle) { // Select the paragraph break cursor.goLeft((short) 1, true); @@ -62,13 +81,9 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, cursor.setString(""); } } - // List citations = CitationStyleGenerator.generateCitation(entries, style, format, bibDatabaseContext, bibEntryTypesManager); + // OOText bibBody = OOFormat.paragraph(OOText.fromString(bibliography.toString())); -// for (int i = 0; i < citations.size(); i++) { -// BibEntry entry = entries.get(i); -// String citation = citations.get(i); -// writeCitation(document, cursor, entry, citation); -// } + // Numeric styles had newlines } public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { From 739dbc10c3b3f68841ad35fd7adc66e1efde9787 Mon Sep 17 00:00:00 2001 From: subhramit Date: Thu, 8 Aug 2024 22:54:48 +0530 Subject: [PATCH 53/94] Bibliography title stage 3 --- .../oocsltext/CSLCitationOOAdapter.java | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 10445844867..1062232e255 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -19,8 +19,12 @@ import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; +import com.sun.star.beans.XPropertySet; +import com.sun.star.text.ControlCharacter; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; +import com.sun.star.text.XTextRange; +import com.sun.star.uno.UnoRuntime; import org.apache.commons.text.StringEscapeUtils; public class CSLCitationOOAdapter { @@ -47,22 +51,33 @@ public void readExistingMarks() throws Exception { public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { -// XTextCursor bibliographyCursor = document.getText().createTextCursor(); -// bibliographyCursor.gotoEnd(false); -// XTextRange titleRange = bibliographyCursor.getStart(); -// titleRange.setString(BIBLIOGRAPHY_TITLE); -// XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); -// titleProps.setPropertyValue("ParaStyleName", BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); -// -// // Clear formatting after the title -// bibliographyCursor.gotoEnd(false); -// bibliographyCursor.goRight((short) 1, false); // Move to the start of the next paragraph -// XPropertySet paragraphProps = UnoRuntime.queryInterface(XPropertySet.class, bibliographyCursor); -// paragraphProps.setPropertyValue("ParaStyleName", "Default Paragraph Style"); // Or use your default style name - OOText title = OOFormat.paragraph(OOText.fromString(BIBLIOGRAPHY_TITLE), BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); - OOTextIntoOO.write(document, cursor, OOText.fromString(title.toString())); - OOText ooBreak = OOFormat.paragraph(OOText.fromString(""), "Body Text"); - OOTextIntoOO.write(document, cursor, ooBreak); + XTextCursor bibliographyCursor = document.getText().createTextCursor(); + bibliographyCursor.gotoEnd(false); + // My approach: + // Insert the bibliography title + XTextRange titleRange = bibliographyCursor.getStart(); + titleRange.setString(BIBLIOGRAPHY_TITLE); + + // Set the paragraph style for the title + XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); + titleProps.setPropertyValue("ParaStyleName", BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); + + // Move the cursor to the end of the title + bibliographyCursor.gotoEnd(false); + + // Insert a paragraph break after the title + bibliographyCursor.getText().insertControlCharacter(bibliographyCursor, ControlCharacter.PARAGRAPH_BREAK, false); + + // Create a new paragraph for references and set its style + XTextRange refParagraph = bibliographyCursor.getStart(); + XPropertySet refParaProps = UnoRuntime.queryInterface(XPropertySet.class, refParagraph); + refParaProps.setPropertyValue("ParaStyleName", "Body Text"); + + // antalk2's derivative +// OOText title = OOFormat.paragraph(OOText.fromString(BIBLIOGRAPHY_TITLE), BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); +// OOTextIntoOO.write(document, cursor, OOText.fromString(title.toString())); +// OOText ooBreak = OOFormat.paragraph(OOText.fromString(""), "Body Text"); +// OOTextIntoOO.write(document, cursor, ooBreak); String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); @@ -81,9 +96,6 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, cursor.setString(""); } } - // OOText bibBody = OOFormat.paragraph(OOText.fromString(bibliography.toString())); - - // Numeric styles had newlines } public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { From 84d4a5b1685dd23407e2ad3cfe44861a660ce1d6 Mon Sep 17 00:00:00 2001 From: subhramit Date: Fri, 9 Aug 2024 00:21:18 +0530 Subject: [PATCH 54/94] Bibliography title stage 5 --- .../oocsltext/CSLCitationOOAdapter.java | 92 +++++++++++++------ 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 1062232e255..bf90995bda0 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -3,6 +3,7 @@ import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -15,16 +16,17 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.model.entry.field.StandardField; +import org.jabref.model.openoffice.DocumentAnnotation; import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; +import org.jabref.model.openoffice.uno.NoDocumentException; +import org.jabref.model.openoffice.uno.UnoTextSection; -import com.sun.star.beans.XPropertySet; -import com.sun.star.text.ControlCharacter; +import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import com.sun.star.text.XTextRange; -import com.sun.star.uno.UnoRuntime; import org.apache.commons.text.StringEscapeUtils; public class CSLCitationOOAdapter { @@ -49,45 +51,68 @@ public void readExistingMarks() throws Exception { markManager.readExistingMarks(); } + public static Optional getBibliographyRange(XTextDocument doc) + throws + NoDocumentException, + WrappedTargetException { + return UnoTextSection.getAnchor(doc, "CSL_bibliography"); + } + public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { - XTextCursor bibliographyCursor = document.getText().createTextCursor(); - bibliographyCursor.gotoEnd(false); - // My approach: - // Insert the bibliography title - XTextRange titleRange = bibliographyCursor.getStart(); - titleRange.setString(BIBLIOGRAPHY_TITLE); - - // Set the paragraph style for the title - XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); - titleProps.setPropertyValue("ParaStyleName", BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); - - // Move the cursor to the end of the title - bibliographyCursor.gotoEnd(false); - - // Insert a paragraph break after the title - bibliographyCursor.getText().insertControlCharacter(bibliographyCursor, ControlCharacter.PARAGRAPH_BREAK, false); - - // Create a new paragraph for references and set its style - XTextRange refParagraph = bibliographyCursor.getStart(); - XPropertySet refParaProps = UnoRuntime.queryInterface(XPropertySet.class, refParagraph); - refParaProps.setPropertyValue("ParaStyleName", "Body Text"); +// XTextCursor bibliographyCursor = document.getText().createTextCursor(); +// bibliographyCursor.gotoEnd(false); +// // My approach: +// // Insert the bibliography title +// XTextRange titleRange = bibliographyCursor.getStart(); +// titleRange.setString(BIBLIOGRAPHY_TITLE); +// +// // Set the paragraph style for the title +// XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); +// titleProps.setPropertyValue("ParaStyleName", BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); +// +// // Move the cursor to the end of the title +// bibliographyCursor.gotoEnd(false); +// +// // Insert a paragraph break after the title +// bibliographyCursor.getText().insertControlCharacter(bibliographyCursor, ControlCharacter.PARAGRAPH_BREAK, false); +// +// // Create a new paragraph for references and set its style +// XTextRange refParagraph = bibliographyCursor.getStart(); +// XPropertySet refParaProps = UnoRuntime.queryInterface(XPropertySet.class, refParagraph); +// refParaProps.setPropertyValue("ParaStyleName", "Body Text"); + // Always creating at the end of the document. + // Alternatively, we could receive a cursor. + XTextCursor textCursor = document.getText().createTextCursor(); + textCursor.gotoEnd(false); + DocumentAnnotation annotation = new DocumentAnnotation(document, "CSL_bibliography", textCursor, false); + UnoTextSection.create(annotation); // antalk2's derivative -// OOText title = OOFormat.paragraph(OOText.fromString(BIBLIOGRAPHY_TITLE), BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); -// OOTextIntoOO.write(document, cursor, OOText.fromString(title.toString())); -// OOText ooBreak = OOFormat.paragraph(OOText.fromString(""), "Body Text"); -// OOTextIntoOO.write(document, cursor, ooBreak); + OOText title = OOFormat.paragraph(OOText.fromString(BIBLIOGRAPHY_TITLE), BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); + OOTextIntoOO.write(document, cursor, OOText.fromString(title.toString())); + OOText ooBreak = OOFormat.paragraph(OOText.fromString(""), "Body Text"); + OOTextIntoOO.write(document, cursor, ooBreak); String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); // Sort entries based on their order of appearance in the document entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); - for (BibEntry entry : entries) { String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); - writeCitation(document, cursor, entry, citation); + String citationKey = entry.getCitationKey().orElse(""); + int currentNumber = markManager.getCitationNumber(citationKey); + + String formattedCitation; + if (isNumericStyle) { + formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); + } else { + formattedCitation = transformHtml(citation); + } + OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); + + OOTextIntoOO.write(document, cursor, ooText); if (isNumericStyle) { // Select the paragraph break cursor.goLeft((short) 1, true); @@ -96,6 +121,13 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, cursor.setString(""); } } + // remove the initial empty paragraph from the section. + XTextRange sectionRange = getBibliographyRange(document).orElseThrow(IllegalStateException::new); + XTextCursor initialParagraph = document.getText().createTextCursorByRange(sectionRange); + initialParagraph.collapseToStart(); + initialParagraph.goRight((short) 1, true); + initialParagraph.setString(""); + // TODO: Chris help } public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { From 6992024636aba6ba34c5b5fa4eab888fd4cc3b60 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 8 Aug 2024 21:31:59 +0200 Subject: [PATCH 55/94] remove duplicate code --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 9bebe64209e..f814b0139f9 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -118,12 +118,6 @@ public void guiActionSelectDocument(boolean autoSelectForSingle) { initializeCitationAdapter(this.getXTextDocument().get()); dialogService.notify(Localization.lang("Connected to document") + ": " + this.getCurrentDocumentTitle().orElse("")); - try { - this.cslCitationOOAdapter = new CSLCitationOOAdapter(this.getXTextDocument().get()); - this.cslCitationOOAdapter.readExistingMarks(); - } catch (Exception e) { - LOGGER.error("Error initializing CSLCitationOOAdapter", e); - } } } From 0a3437c9aded10d1445c37e36d063a74ece85a0e Mon Sep 17 00:00:00 2001 From: subhramit Date: Fri, 9 Aug 2024 01:45:17 +0530 Subject: [PATCH 56/94] Bibliography title stage 7 --- .../oocsltext/CSLCitationOOAdapter.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index bf90995bda0..86a49cced43 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -16,7 +16,6 @@ import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.model.entry.field.StandardField; -import org.jabref.model.openoffice.DocumentAnnotation; import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; @@ -83,10 +82,10 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, // refParaProps.setPropertyValue("ParaStyleName", "Body Text"); // Always creating at the end of the document. // Alternatively, we could receive a cursor. - XTextCursor textCursor = document.getText().createTextCursor(); - textCursor.gotoEnd(false); - DocumentAnnotation annotation = new DocumentAnnotation(document, "CSL_bibliography", textCursor, false); - UnoTextSection.create(annotation); +// XTextCursor textCursor = document.getText().createTextCursor(); +// textCursor.gotoEnd(false); +// DocumentAnnotation annotation = new DocumentAnnotation(document, "CSL_bibliography", textCursor, false); +// UnoTextSection.create(annotation); // antalk2's derivative OOText title = OOFormat.paragraph(OOText.fromString(BIBLIOGRAPHY_TITLE), BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); @@ -103,6 +102,7 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); String citationKey = entry.getCitationKey().orElse(""); int currentNumber = markManager.getCitationNumber(citationKey); + System.out.println(citation); String formattedCitation; if (isNumericStyle) { @@ -122,12 +122,12 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, } } // remove the initial empty paragraph from the section. - XTextRange sectionRange = getBibliographyRange(document).orElseThrow(IllegalStateException::new); - XTextCursor initialParagraph = document.getText().createTextCursorByRange(sectionRange); - initialParagraph.collapseToStart(); - initialParagraph.goRight((short) 1, true); - initialParagraph.setString(""); - // TODO: Chris help +// XTextRange sectionRange = getBibliographyRange(document).orElseThrow(IllegalStateException::new); +// XTextCursor initialParagraph = document.getText().createTextCursorByRange(sectionRange); +// initialParagraph.collapseToStart(); +// initialParagraph.goRight((short) 1, true); +// initialParagraph.setString(""); +// // TODO: Chris help - newlines!! } public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { From 56d897055e0a57b1017618a431a4bf1324dd8f94 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 10 Aug 2024 01:55:08 +0530 Subject: [PATCH 57/94] Fix updateSingleCitation --- .../openoffice/oocsltext/CSLCitationOOAdapter.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 86a49cced43..7aa0dd395d5 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -283,7 +283,7 @@ private void writeCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry cursor.collapseToEnd(); } - private String updateSingleCitation(String citation, int currentNumber) { + public static String updateSingleCitation(String citation, int currentNumber) { Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); Matcher matcher = pattern.matcher(citation); StringBuilder sb = new StringBuilder(); @@ -294,18 +294,13 @@ private String updateSingleCitation(String citation, int currentNumber) { String prefix = matcher.group(1) != null ? matcher.group(1) : ""; String suffix = matcher.group(3) != null ? matcher.group(3) : ""; String dot = matcher.group(4) != null ? "." : ""; + String space = matcher.group().endsWith(" ") ? " " : ""; - String replacement; - if (prefix.isEmpty() && suffix.isEmpty()) { - replacement = currentNumber + dot + " "; - } else { - replacement = prefix + currentNumber + suffix + dot + " "; - } + String replacement = prefix + currentNumber + suffix + dot + space; matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement)); numberReplaced = true; } else { - // If we've already replaced the number, keep any subsequent numbers as they are matcher.appendReplacement(sb, matcher.group()); } } From 5eb30bb0a8a8e6c0b60d8ab09b43f794d2f3f0c6 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sat, 10 Aug 2024 12:09:37 +0200 Subject: [PATCH 58/94] Support more styles for InText non-numeric citation styles --- .../oocsltext/CSLCitationOOAdapter.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 7aa0dd395d5..2d525a1d4d7 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -30,7 +30,7 @@ public class CSLCitationOOAdapter { - private static final Pattern YEAR_IN_CITATION_PATTERN = Pattern.compile("(.).*?, (\\d{4}.*)"); + private static final Pattern YEAR_IN_CITATION_PATTERN = Pattern.compile("(.)(.*), (\\d{4}.*)"); public static final String[] PREFIXES = {"JABREF_", "CSL_"}; // TODO: These are static final fields right now, should add the functionality to let user select these and store them in preferences. public static final String BIBLIOGRAPHY_TITLE = "References"; @@ -166,16 +166,17 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle BibEntry currentEntry = iterator.next(); String inTextCitation = CitationStyleGenerator.generateInText(List.of(currentEntry), style, format, bibDatabaseContext, bibEntryTypesManager).getText(); String formattedCitation = transformHtml(inTextCitation); + String finalText; if (isNumericStyle) { formattedCitation = updateMultipleCitations(formattedCitation, List.of(currentEntry)); + String prefix = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) + .map(authors -> AuthorList.parse(authors)) + .map(list -> BracketedPattern.joinAuthorsOnLastName(list, 1, "", " et al.") + " ") + .orElse(""); + finalText = prefix + formattedCitation; } else { - formattedCitation = extractYear(formattedCitation); + finalText = changeToInText(formattedCitation); } - String prefix = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) - .map(authors -> AuthorList.parse(authors)) - .map(list -> BracketedPattern.joinAuthorsOnLastName(list, 1, "", " et al.") + " ") - .orElse(""); - String finalText = prefix + formattedCitation; if (iterator.hasNext()) { finalText += ","; // The next space is inserted somehow magically by other routines. Therefore, we do not add a space here. @@ -186,10 +187,10 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle } } - private String extractYear(String formattedCitation) { + private String changeToInText(String formattedCitation) { Matcher matcher = YEAR_IN_CITATION_PATTERN.matcher(formattedCitation); if (matcher.find()) { - return matcher.group(1) + matcher.group(2); + return matcher.group(2) + " " + matcher.group(1) + matcher.group(3); } return formattedCitation; } From f512086e7569f4985e32e5a49b29c6601855b90f Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sat, 10 Aug 2024 12:12:01 +0200 Subject: [PATCH 59/94] Make "authorsAlpha" public --- .../org/jabref/logic/citationkeypattern/BracketedPattern.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java b/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java index b1603a16651..f2b1d393afd 100644 --- a/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java +++ b/src/main/java/org/jabref/logic/citationkeypattern/BracketedPattern.java @@ -844,7 +844,7 @@ static String allAuthors(AuthorList authorList) { * @param authorList an {@link AuthorList} * @return the initials of all authors' names */ - static String authorsAlpha(AuthorList authorList) { + public static String authorsAlpha(AuthorList authorList) { StringBuilder alphaStyle = new StringBuilder(); int maxAuthors; final boolean maxAuthorsExceeded; From 9eddf9de2a41be325a5030d667a80f2f530b050c Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 10 Aug 2024 16:57:45 +0530 Subject: [PATCH 60/94] Implement auto-select last used style tab --- .../jabref/gui/openoffice/StyleSelectDialogView.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java index 5f6972505a7..00c47467bd3 100644 --- a/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java +++ b/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogView.java @@ -191,6 +191,18 @@ private void initialize() { } }); + OOStyle currentStyle = preferencesService.getOpenOfficePreferences().getCurrentStyle(); + if (currentStyle instanceof JStyle) { + tabPane.getSelectionModel().select(1); + } else { + tabPane.getSelectionModel().select(0); + } + + viewModel.setSelectedTab(tabPane.getSelectionModel().getSelectedItem()); + tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { + viewModel.setSelectedTab(newValue); + }); + updateCurrentStyleLabel(); } From 49851be11d70b02554858d5ac4e5eb16d2e4e850 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sat, 10 Aug 2024 15:40:25 +0200 Subject: [PATCH 61/94] Fix checkstyle --- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 2d525a1d4d7..c50b58c07d9 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -30,12 +30,11 @@ public class CSLCitationOOAdapter { - private static final Pattern YEAR_IN_CITATION_PATTERN = Pattern.compile("(.)(.*), (\\d{4}.*)"); - public static final String[] PREFIXES = {"JABREF_", "CSL_"}; // TODO: These are static final fields right now, should add the functionality to let user select these and store them in preferences. public static final String BIBLIOGRAPHY_TITLE = "References"; public static final String BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT = "Heading 2"; + private static final Pattern YEAR_IN_CITATION_PATTERN = Pattern.compile("(.)(.*), (\\d{4}.*)"); private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; private final CSLReferenceMarkManager markManager; From 0aead544dad801e06ee1f9ade2fa84c0e23daa89 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sat, 10 Aug 2024 19:13:25 +0530 Subject: [PATCH 62/94] Add support for alphanumeric citations --- .../oocsltext/CSLCitationOOAdapter.java | 109 +++++++++++++++++- src/main/resources/csl-styles | 2 +- 2 files changed, 104 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 2d525a1d4d7..0143d24f6ad 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -12,6 +12,7 @@ import org.jabref.logic.citationstyle.CitationStyleGenerator; import org.jabref.logic.citationstyle.CitationStyleOutputFormat; import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.Author; import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibEntryTypesManager; @@ -35,6 +36,7 @@ public class CSLCitationOOAdapter { // TODO: These are static final fields right now, should add the functionality to let user select these and store them in preferences. public static final String BIBLIOGRAPHY_TITLE = "References"; public static final String BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT = "Heading 2"; + private static final int MAX_ALPHA_AUTHORS = 4; private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; @@ -133,9 +135,14 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); + boolean isAlphanumeric = isAlphanumericStyle(selectedStyle); - // Generate a single in-text citation for a group of entries - String inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); + String inTextCitation; + if (isAlphanumeric) { + inTextCitation = generateAlphanumericCitation(entries, bibDatabaseContext); + } else { + inTextCitation = CitationStyleGenerator.generateInText(entries, style, format, bibDatabaseContext, bibEntryTypesManager).getText(); + } String formattedCitation = transformHtml(inTextCitation); @@ -158,13 +165,25 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle throws Exception { String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); - - boolean twoEntries = entries.size() == 2; + boolean isAlphanumeric = isAlphanumericStyle(selectedStyle); Iterator iterator = entries.iterator(); while (iterator.hasNext()) { BibEntry currentEntry = iterator.next(); - String inTextCitation = CitationStyleGenerator.generateInText(List.of(currentEntry), style, format, bibDatabaseContext, bibEntryTypesManager).getText(); + String inTextCitation; + if (isAlphanumeric) { + // Generate the alphanumeric citation + inTextCitation = generateAlphanumericCitation(List.of(currentEntry), bibDatabaseContext); + // Get the author's name + String authorName = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) + .map(authors -> AuthorList.parse(authors)) + .map(list -> BracketedPattern.joinAuthorsOnLastName(list, 1, "", " et al.")) + .orElse(""); + // Combine author name with the citation + inTextCitation = authorName + " " + inTextCitation; + } else { + inTextCitation = CitationStyleGenerator.generateInText(List.of(currentEntry), style, format, bibDatabaseContext, bibEntryTypesManager).getText(); + } String formattedCitation = transformHtml(inTextCitation); String finalText; if (isNumericStyle) { @@ -174,12 +193,13 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle .map(list -> BracketedPattern.joinAuthorsOnLastName(list, 1, "", " et al.") + " ") .orElse(""); finalText = prefix + formattedCitation; + } else if (isAlphanumeric) { + finalText = formattedCitation; } else { finalText = changeToInText(formattedCitation); } if (iterator.hasNext()) { finalText += ","; - // The next space is inserted somehow magically by other routines. Therefore, we do not add a space here. } OOText ooText = OOFormat.setLocaleNone(OOText.fromString(finalText)); insertMultipleReferenceMarks(cursor, List.of(currentEntry), ooText); @@ -355,4 +375,81 @@ public boolean isCitedEntry(BibEntry entry) { String citationKey = entry.getCitationKey().orElse(""); return markManager.hasCitationForKey(citationKey); } + + private String generateAlphanumericCitation(List entries, BibDatabaseContext bibDatabaseContext) { + StringBuilder citation = new StringBuilder("["); + for (int i = 0; i < entries.size(); i++) { + BibEntry entry = entries.get(i); + Optional author = entry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()); + Optional year = entry.getResolvedFieldOrAlias(StandardField.YEAR, bibDatabaseContext.getDatabase()); + + if (author.isPresent() && year.isPresent()) { + AuthorList authorList = AuthorList.parse(author.get()); + String alphaKey = authorsAlpha(authorList); + + // Extract last two digits of the year + String shortYear = year.get().length() >= 2 ? + year.get().substring(year.get().length() - 2) : + year.get(); + + citation.append(alphaKey).append(shortYear); + } else { + citation.append(entry.getCitationKey().orElse("")); + } + + if (i < entries.size() - 1) { + citation.append("; "); + } + } + citation.append("]"); + return citation.toString(); + } + + private boolean isAlphanumericStyle(CitationStyle style) { + return "DIN 1505-2 (alphanumeric, Deutsch) - standard superseded by ISO-690".equals(style.getTitle()); + } + + public static String authorsAlpha(AuthorList authorList) { + StringBuilder alphaStyle = new StringBuilder(); + int maxAuthors; + final boolean maxAuthorsExceeded; + if (authorList.getNumberOfAuthors() <= MAX_ALPHA_AUTHORS) { + maxAuthors = authorList.getNumberOfAuthors(); + maxAuthorsExceeded = false; + } else { + maxAuthors = MAX_ALPHA_AUTHORS; + maxAuthorsExceeded = true; + } + + if (authorList.getNumberOfAuthors() == 1) { + String[] firstAuthor = authorList.getAuthor(0).getNamePrefixAndFamilyName() + .replaceAll("\\s+", " ").trim().split(" "); + // take first letter of any "prefixes" (e.g. van der Aalst -> vd) + for (int j = 0; j < (firstAuthor.length - 1); j++) { + alphaStyle.append(firstAuthor[j], 0, 1); + } + // append last part of last name completely + alphaStyle.append(firstAuthor[firstAuthor.length - 1], 0, + Math.min(4, firstAuthor[firstAuthor.length - 1].length())); + } else { + boolean andOthersPresent = authorList.getAuthor(maxAuthors - 1).equals(Author.OTHERS); + if (andOthersPresent) { + maxAuthors--; + } + List vonAndLastNames = authorList.getAuthors().stream() + .limit(maxAuthors) + .map(Author::getNamePrefixAndFamilyName) + .toList(); + for (String vonAndLast : vonAndLastNames) { + // replace all whitespaces by " " + // split the lastname at " " + String[] nameParts = vonAndLast.replaceAll("\\s+", " ").trim().split(" "); + for (String part : nameParts) { + // use first character of each part of lastname + alphaStyle.append(part, 0, 1); + } + } + } + return alphaStyle.toString(); + } } diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index df939b87950..bf2926b71a9 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit df939b87950c9f22a98e7a8188bbeabbc307bb42 +Subproject commit bf2926b71a969644ce735760977d1246aed1f2e2 From fe4b446b50a75ea5c2dda307317f47a3271aadbc Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 20:40:53 +0530 Subject: [PATCH 63/94] Remove duplicated code --- .../org/jabref/gui/openoffice/OOBibBase.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index f814b0139f9..812d4b7e1da 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -605,17 +605,17 @@ public void guiActionInsertEntry(List entries, if (style instanceof CitationStyle citationStyle) { // Handle insertion of CSL Style citations - CSLCitationOOAdapter adapter = new CSLCitationOOAdapter(doc); - adapter.readExistingMarks(); + initializeCitationAdapter(doc); + if (citationType == CitationType.AUTHORYEAR_PAR) { // "Cite" button - adapter.insertCitation(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + this.cslCitationOOAdapter.insertCitation(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } else if (citationType == CitationType.AUTHORYEAR_INTEXT) { // "Cite in-text" button - adapter.insertInTextCitation(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); + this.cslCitationOOAdapter.insertInTextCitation(cursor.get(), citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); } else if (citationType == CitationType.INVISIBLE_CIT) { // "Insert empty citation" - adapter.insertEmpty(cursor.get(), entries); + this.cslCitationOOAdapter.insertEmpty(cursor.get(), entries); } } else if (style instanceof JStyle jStyle) { // Handle insertion of JStyle citations @@ -910,14 +910,13 @@ public void guiActionUpdateDocument(List databases, OOStyle style) try { UnoUndo.enterUndoContext(doc, "Create CSL bibliography"); - CSLCitationOOAdapter adapter = new CSLCitationOOAdapter(doc); - adapter.readExistingMarks(); + initializeCitationAdapter(doc); // Collect only cited entries from all databases List citedEntries = new ArrayList<>(); for (BibDatabase database : databases) { for (BibEntry entry : database.getEntries()) { - if (adapter.isCitedEntry(entry)) { + if (cslCitationOOAdapter.isCitedEntry(entry)) { citedEntries.add(entry); } } @@ -936,7 +935,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) BibDatabase bibDatabase = new BibDatabase(citedEntries); BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(bibDatabase); - CSLUpdateBibliography.rebuildCSLBibliography(doc, adapter, citedEntries, citationStyle, bibDatabaseContext, Injector.instantiateModelOrService(BibEntryTypesManager.class)); + CSLUpdateBibliography.rebuildCSLBibliography(doc, cslCitationOOAdapter, citedEntries, citationStyle, bibDatabaseContext, Injector.instantiateModelOrService(BibEntryTypesManager.class)); // // Create a new cursor at the end of the document for bibliography insertion // XTextCursor bibliographyCursor = doc.getText().createTextCursor(); From 8c66b710b47662b9202989f7cdc7851fb6fcf800 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 21:15:19 +0530 Subject: [PATCH 64/94] Enhanced exception handling --- .../org/jabref/gui/openoffice/OOBibBase.java | 51 ++++----- .../gui/openoffice/OpenOfficePanel.java | 20 +++- .../oocsltext/CSLCitationOOAdapter.java | 101 +++--------------- .../oocsltext/CSLReferenceMark.java | 4 +- .../oocsltext/CSLReferenceMarkManager.java | 5 +- .../oocsltext/CSLUpdateBibliography.java | 4 +- 6 files changed, 61 insertions(+), 124 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 812d4b7e1da..6df1d10890b 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -1,5 +1,6 @@ package org.jabref.gui.openoffice; +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -54,6 +55,7 @@ import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; +import com.sun.star.uno.Exception; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,16 +90,12 @@ public OOBibBase(Path loPath, DialogService dialogService) this.alwaysAddCitedOnPages = false; } - private void initializeCitationAdapter(XTextDocument doc) { - try { + private void initializeCitationAdapter(XTextDocument doc) throws WrappedTargetException, NoSuchElementException { this.cslCitationOOAdapter = new CSLCitationOOAdapter(doc); this.cslCitationOOAdapter.readExistingMarks(); - } catch (Exception e) { - LOGGER.error("Error initializing CSLCitationOOAdapter", e); - } } - public void guiActionSelectDocument(boolean autoSelectForSingle) { + public void guiActionSelectDocument(boolean autoSelectForSingle) throws WrappedTargetException, NoSuchElementException { final String errorTitle = Localization.lang("Problem connecting"); try { @@ -637,9 +635,16 @@ public void guiActionInsertEntry(List entries, OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); } catch (DisposedException ex) { OOError.from(ex).setTitle(errorTitle).showErrorDialog(dialogService); - } catch (Exception ex) { + } catch (CreationException + | WrappedTargetException + | IOException + | PropertyVetoException + | IllegalTypeException + | NotRemoveableException ex) { LOGGER.warn("Could not insert entry", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); + } catch (Exception e) { + throw new RuntimeException(e); } finally { UnoUndo.leaveUndoContext(doc); } @@ -937,36 +942,16 @@ public void guiActionUpdateDocument(List databases, OOStyle style) CSLUpdateBibliography.rebuildCSLBibliography(doc, cslCitationOOAdapter, citedEntries, citationStyle, bibDatabaseContext, Injector.instantiateModelOrService(BibEntryTypesManager.class)); -// // Create a new cursor at the end of the document for bibliography insertion -// XTextCursor bibliographyCursor = doc.getText().createTextCursor(); -// bibliographyCursor.gotoEnd(false); -// -// // Insert bibliography title -// String bibliographyTitle = Localization.lang("\nReferences"); -// bibliographyCursor.setString("\n"); -// -// // Apply formatting to the title (here, we make it bold and larger) -// XTextRange titleRange = bibliographyCursor.getStart(); -// titleRange.setString(bibliographyTitle); -// XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); -// titleProps.setPropertyValue("CharWeight", com.sun.star.awt.FontWeight.BOLD); -// titleProps.setPropertyValue("CharHeight", 16f); -// -// // Move cursor to prevent reference mark bleed-out (current implementation) TODO: Remove once bleed-out is fixed -// bibliographyCursor.goRight((short) 1, false); -// -// // Insert bibliography entries -// // BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(databases.getFirst()); -// // TODO: Ask Chris if injecting database context is a good idea -// BibDatabaseContext bibDatabaseContext = Injector.instantiateModelOrService(BibDatabaseContext.class); -// BibEntryTypesManager bibEntryTypesManager = Injector.instantiateModelOrService(BibEntryTypesManager.class); -// -// adapter.insertBibliography(bibliographyCursor, citationStyle, citedEntries, bibDatabaseContext, bibEntryTypesManager); + } catch (NoDocumentException + | NoSuchElementException e) { + throw new RuntimeException(e); } finally { UnoUndo.leaveUndoContext(doc); fcursor.get().restore(doc); } - } catch (Exception ex) { + } catch (CreationException + | WrappedTargetException + | com.sun.star.lang.IllegalArgumentException ex) { LOGGER.warn("Could not create bibliography", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } diff --git a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java index ebd67605480..539602c4820 100644 --- a/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java +++ b/src/main/java/org/jabref/gui/openoffice/OpenOfficePanel.java @@ -62,6 +62,8 @@ import org.jabref.preferences.PreferencesService; import com.sun.star.comp.helper.BootstrapException; +import com.sun.star.container.NoSuchElementException; +import com.sun.star.lang.WrappedTargetException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -196,7 +198,14 @@ private void initPanel() { manualConnect.setOnAction(e -> connectManually()); selectDocument.setTooltip(new Tooltip(Localization.lang("Select which open Writer document to work on"))); - selectDocument.setOnAction(e -> ooBase.guiActionSelectDocument(false)); + selectDocument.setOnAction(e -> { + try { + ooBase.guiActionSelectDocument(false); + } catch (WrappedTargetException + | NoSuchElementException ex) { + throw new RuntimeException(ex); + } + }); setStyleFile.setMaxWidth(Double.MAX_VALUE); setStyleFile.setOnAction(event -> { @@ -404,7 +413,7 @@ private void updateButtonAvailability() { private void connect() { Task connectTask = new Task<>() { @Override - protected OOBibBase call() throws Exception { + protected OOBibBase call() throws BootstrapException, CreationException { updateProgress(ProgressBar.INDETERMINATE_PROGRESS, ProgressBar.INDETERMINATE_PROGRESS); Path path = Path.of(preferencesService.getOpenOfficePreferences().getExecutablePath()); @@ -415,7 +424,12 @@ protected OOBibBase call() throws Exception { connectTask.setOnSucceeded(value -> { ooBase = connectTask.getValue(); - ooBase.guiActionSelectDocument(true); + try { + ooBase.guiActionSelectDocument(true); + } catch (WrappedTargetException + | NoSuchElementException e) { + throw new RuntimeException(e); + } // Enable actions that depend on a connection updateButtonAvailability(); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index f6f9ba9ccf7..c61fc6538e6 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -1,5 +1,6 @@ package org.jabref.logic.openoffice.oocsltext; +import java.io.IOException; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -20,13 +21,13 @@ import org.jabref.model.openoffice.ootext.OOFormat; import org.jabref.model.openoffice.ootext.OOText; import org.jabref.model.openoffice.ootext.OOTextIntoOO; -import org.jabref.model.openoffice.uno.NoDocumentException; -import org.jabref.model.openoffice.uno.UnoTextSection; +import org.jabref.model.openoffice.uno.CreationException; +import com.sun.star.container.NoSuchElementException; import com.sun.star.lang.WrappedTargetException; import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; -import com.sun.star.text.XTextRange; +import com.sun.star.uno.Exception; import org.apache.commons.text.StringEscapeUtils; public class CSLCitationOOAdapter { @@ -42,53 +43,18 @@ public class CSLCitationOOAdapter { private final CSLReferenceMarkManager markManager; private boolean isNumericStyle = false; - public CSLCitationOOAdapter(XTextDocument doc) throws Exception { + public CSLCitationOOAdapter(XTextDocument doc) { this.document = doc; this.markManager = new CSLReferenceMarkManager(doc); } - public void readExistingMarks() throws Exception { + public void readExistingMarks() throws WrappedTargetException, NoSuchElementException { markManager.readExistingMarks(); } - public static Optional getBibliographyRange(XTextDocument doc) - throws - NoDocumentException, - WrappedTargetException { - return UnoTextSection.getAnchor(doc, "CSL_bibliography"); - } - public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws Exception { -// XTextCursor bibliographyCursor = document.getText().createTextCursor(); -// bibliographyCursor.gotoEnd(false); -// // My approach: -// // Insert the bibliography title -// XTextRange titleRange = bibliographyCursor.getStart(); -// titleRange.setString(BIBLIOGRAPHY_TITLE); -// -// // Set the paragraph style for the title -// XPropertySet titleProps = UnoRuntime.queryInterface(XPropertySet.class, titleRange); -// titleProps.setPropertyValue("ParaStyleName", BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); -// -// // Move the cursor to the end of the title -// bibliographyCursor.gotoEnd(false); -// -// // Insert a paragraph break after the title -// bibliographyCursor.getText().insertControlCharacter(bibliographyCursor, ControlCharacter.PARAGRAPH_BREAK, false); -// -// // Create a new paragraph for references and set its style -// XTextRange refParagraph = bibliographyCursor.getStart(); -// XPropertySet refParaProps = UnoRuntime.queryInterface(XPropertySet.class, refParagraph); -// refParaProps.setPropertyValue("ParaStyleName", "Body Text"); - // Always creating at the end of the document. - // Alternatively, we could receive a cursor. -// XTextCursor textCursor = document.getText().createTextCursor(); -// textCursor.gotoEnd(false); -// DocumentAnnotation annotation = new DocumentAnnotation(document, "CSL_bibliography", textCursor, false); -// UnoTextSection.create(annotation); - - // antalk2's derivative + throws WrappedTargetException, CreationException { + OOText title = OOFormat.paragraph(OOText.fromString(BIBLIOGRAPHY_TITLE), BIBLIOGRAPHY_HEADER_PARAGRAPH_FORMAT); OOTextIntoOO.write(document, cursor, OOText.fromString(title.toString())); OOText ooBreak = OOFormat.paragraph(OOText.fromString(""), "Body Text"); @@ -122,16 +88,10 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, cursor.setString(""); } } - // remove the initial empty paragraph from the section. -// XTextRange sectionRange = getBibliographyRange(document).orElseThrow(IllegalStateException::new); -// XTextCursor initialParagraph = document.getText().createTextCursorByRange(sectionRange); -// initialParagraph.collapseToStart(); -// initialParagraph.goRight((short) 1, true); -// initialParagraph.setString(""); -// // TODO: Chris help - newlines!! } - public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws Exception { + public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) + throws CreationException, IOException, Exception { String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); boolean isAlphanumeric = isAlphanumericStyle(selectedStyle); @@ -161,7 +121,7 @@ public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List * @implNote Very similar to the {@link #insertCitation(XTextCursor, CitationStyle, List, BibDatabaseContext, BibEntryTypesManager)} method.insertInText method */ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws Exception { + throws IOException, CreationException, Exception { String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); boolean isAlphanumeric = isAlphanumericStyle(selectedStyle); @@ -175,7 +135,7 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle inTextCitation = generateAlphanumericCitation(List.of(currentEntry), bibDatabaseContext); // Get the author's name String authorName = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) - .map(authors -> AuthorList.parse(authors)) + .map(AuthorList::parse) .map(list -> BracketedPattern.joinAuthorsOnLastName(list, 1, "", " et al.")) .orElse(""); // Combine author name with the citation @@ -188,7 +148,7 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle if (isNumericStyle) { formattedCitation = updateMultipleCitations(formattedCitation, List.of(currentEntry)); String prefix = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) - .map(authors -> AuthorList.parse(authors)) + .map(AuthorList::parse) .map(list -> BracketedPattern.joinAuthorsOnLastName(list, 1, "", " et al.") + " ") .orElse(""); finalText = prefix + formattedCitation; @@ -215,7 +175,7 @@ private String changeToInText(String formattedCitation) { } public void insertEmpty(XTextCursor cursor, List entries) - throws Exception { + throws CreationException, Exception { for (BibEntry entry : entries) { CSLReferenceMark mark = markManager.createReferenceMark(entry); OOText emptyOOText = OOFormat.setLocaleNone(OOText.fromString("")); @@ -226,7 +186,8 @@ public void insertEmpty(XTextCursor cursor, List entries) cursor.collapseToEnd(); } - private void insertMultipleReferenceMarks(XTextCursor cursor, List entries, OOText ooText) throws Exception { + private void insertMultipleReferenceMarks(XTextCursor cursor, List entries, OOText ooText) + throws CreationException, Exception { boolean preceedingSpaceExists; XTextCursor checkCursor = cursor.getText().createTextCursorByRange(cursor.getStart()); @@ -283,26 +244,6 @@ private String updateMultipleCitations(String citation, List entries) return sb.toString(); } - private void writeCitation(XTextDocument doc, XTextCursor cursor, BibEntry entry, String citation) throws Exception { - String citationKey = entry.getCitationKey().orElse(""); - int currentNumber = markManager.getCitationNumber(citationKey); - - CSLReferenceMark mark = markManager.createReferenceMark(entry); - String formattedCitation; - if (isNumericStyle) { - formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); - } else { - formattedCitation = transformHtml(citation); - } - OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); - - // Insert the citation text wrapped in a reference mark - mark.insertReferenceIntoOO(doc, cursor, ooText, false, false, true); - - // Move the cursor to the end of the inserted text - cursor.collapseToEnd(); - } - public static String updateSingleCitation(String citation, int currentNumber) { Pattern pattern = Pattern.compile("(\\[|\\()?(\\d+)(\\]|\\))?(\\.)?\\s*"); Matcher matcher = pattern.matcher(citation); @@ -410,15 +351,7 @@ private boolean isAlphanumericStyle(CitationStyle style) { public static String authorsAlpha(AuthorList authorList) { StringBuilder alphaStyle = new StringBuilder(); - int maxAuthors; - final boolean maxAuthorsExceeded; - if (authorList.getNumberOfAuthors() <= MAX_ALPHA_AUTHORS) { - maxAuthors = authorList.getNumberOfAuthors(); - maxAuthorsExceeded = false; - } else { - maxAuthors = MAX_ALPHA_AUTHORS; - maxAuthorsExceeded = true; - } + int maxAuthors = Math.min(authorList.getNumberOfAuthors(), MAX_ALPHA_AUTHORS); if (authorList.getNumberOfAuthors() == 1) { String[] firstAuthor = authorList.getAuthor(0).getNamePrefixAndFamilyName() diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java index da6265fce42..49f11127c0c 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMark.java @@ -8,6 +8,7 @@ import org.jabref.model.openoffice.uno.UnoReferenceMark; import com.sun.star.container.XNamed; +import com.sun.star.lang.WrappedTargetException; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.text.XTextContent; import com.sun.star.text.XTextCursor; @@ -49,7 +50,8 @@ public static CSLReferenceMark of(String citationKey, Integer citationNumber, XM return new CSLReferenceMark(named, name, citationKey, citationNumber, uniqueId); } - public void insertReferenceIntoOO(XTextDocument doc, XTextCursor position, OOText ooText, boolean insertSpaceBefore, boolean insertSpaceAfter, boolean withoutBrackets) throws Exception, CreationException { + public void insertReferenceIntoOO(XTextDocument doc, XTextCursor position, OOText ooText, boolean insertSpaceBefore, boolean insertSpaceAfter, boolean withoutBrackets) + throws CreationException, WrappedTargetException { // Ensure the cursor is at the end of its range position.collapseToEnd(); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java index 3ea1cc81ebe..027b6662c23 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLReferenceMarkManager.java @@ -9,11 +9,14 @@ import org.jabref.logic.openoffice.ReferenceMark; import org.jabref.model.entry.BibEntry; +import com.sun.star.container.NoSuchElementException; import com.sun.star.container.XNameAccess; import com.sun.star.container.XNamed; +import com.sun.star.lang.WrappedTargetException; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.text.XReferenceMarksSupplier; import com.sun.star.text.XTextDocument; +import com.sun.star.uno.Exception; import com.sun.star.uno.UnoRuntime; import io.github.thibaultmeyer.cuid.CUID; import org.slf4j.Logger; @@ -40,7 +43,7 @@ public CSLReferenceMarkManager(XTextDocument document) { this.citationKeyToNumber = new HashMap<>(); } - public void readExistingMarks() throws Exception { + public void readExistingMarks() throws WrappedTargetException, NoSuchElementException { XReferenceMarksSupplier supplier = UnoRuntime.queryInterface(XReferenceMarksSupplier.class, document); XNameAccess marks = supplier.getReferenceMarks(); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java index 736bb78ec91..e65dc5a94e7 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java @@ -43,7 +43,7 @@ public static void rebuildCSLBibliography(XTextDocument doc, CitationStyle citationStyle, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws Exception { + throws WrappedTargetException, NoDocumentException, CreationException { LOGGER.info("Starting to rebuild CSL bibliography"); // Ensure the bibliography section exists @@ -89,7 +89,7 @@ private static void populateCSLBibTextSection(XTextDocument doc, CitationStyle citationStyle, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) - throws Exception { + throws WrappedTargetException, NoDocumentException, CreationException { LOGGER.info("Populating CSL bibliography section"); Optional sectionRange = getBibliographyRange(doc); From 0b4e657a88935490a5eb655966c91313d8c73a23 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 21:19:18 +0530 Subject: [PATCH 65/94] Enhanced exception handling for isNumericStyle --- .../org/jabref/logic/citationstyle/CitationStyle.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index d6892c68518..dc3baac717a 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -251,10 +251,12 @@ public boolean isNumericStyle() { String citationFormat = categoryElement.getAttribute("citation-format"); return "numeric".equals(citationFormat); - } catch ( - Exception e) { - org.tinylog.Logger.error("Error parsing CSL style XML", e); + } catch (IOException + | ParserConfigurationException e) { + LOGGER.error("Error parsing CSL style XML", e); return false; + } catch (SAXException e) { + throw new RuntimeException(e); } } } From 5a3eed54e5028739dce28717a45073d00e549ba3 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 21:35:24 +0530 Subject: [PATCH 66/94] Upgrade to StAX parsing for isNumericStyle --- .../logic/citationstyle/CitationStyle.java | 113 +++++++++++------- .../oocsltext/CSLCitationOOAdapter.java | 1 + 2 files changed, 72 insertions(+), 42 deletions(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index dc3baac717a..5de97b165e3 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -17,9 +17,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; import org.jabref.architecture.AllowedToUseClassGetResource; import org.jabref.logic.openoffice.style.OOStyle; @@ -27,12 +28,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.w3c.dom.CharacterData; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Representation of a CitationStyle. Stores its name, the file path and the style itself @@ -45,7 +40,7 @@ public class CitationStyle implements OOStyle { private static final Logger LOGGER = LoggerFactory.getLogger(CitationStyle.class); private static final String STYLES_ROOT = "/csl-styles"; private static final List STYLES = new ArrayList<>(); - private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory.newInstance(); + private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance(); private final String filePath; private final String title; @@ -73,28 +68,54 @@ private static Optional createCitationStyleFromSource(final Input } return Optional.of(new CitationStyle(filename, title.get(), content)); - } catch (ParserConfigurationException | SAXException | NullPointerException | IOException e) { + } catch (NullPointerException + | IOException e) { LOGGER.error("Error while parsing source", e); return Optional.empty(); } } - private static Optional getTitle(String filename, String content) throws SAXException, IOException, ParserConfigurationException { - // TODO: Switch to StAX parsing (to speed up - we need only the title) - InputSource inputSource = new InputSource(new StringReader(content)); - Document doc = FACTORY.newDocumentBuilder().parse(inputSource); + private static Optional getTitle(String filename, String content) { + FACTORY.setProperty(XMLInputFactory.IS_COALESCING, true); - // See CSL#canFormatBibliographies, checks if the tag exists - NodeList bibs = doc.getElementsByTagName("bibliography"); - if (bibs.getLength() <= 0) { - LOGGER.debug("no bibliography element for file {} ", filename); + try { + XMLStreamReader reader = FACTORY.createXMLStreamReader(new StringReader(content)); + + boolean inInfo = false; + boolean hasBibliography = false; + String title = ""; + + while (reader.hasNext()) { + int event = reader.next(); + + if (event == XMLStreamConstants.START_ELEMENT) { + String elementName = reader.getLocalName(); + + if ("bibliography".equals(elementName)) { + hasBibliography = true; + } else if ("info".equals(elementName)) { + inInfo = true; + } else if (inInfo && "title".equals(elementName)) { + title = reader.getElementText(); + } + } else if (event == XMLStreamConstants.END_ELEMENT) { + if ("info".equals(reader.getLocalName())) { + inInfo = false; + } + } + } + + if (hasBibliography && title != null) { + return Optional.of(title); + } else { + LOGGER.debug("No valid title or bibliography found for file {}", filename); + return Optional.empty(); + } + } catch ( + XMLStreamException e) { + LOGGER.error("Error parsing XML for file {}: {}", filename, e.getMessage()); return Optional.empty(); } - - NodeList nodes = doc.getElementsByTagName("info"); - NodeList titleNode = ((Element) nodes.item(0)).getElementsByTagName("title"); - String title = ((CharacterData) titleNode.item(0).getFirstChild()).getData(); - return Optional.of(title); } private static String stripInvalidProlog(String source) { @@ -124,9 +145,11 @@ public static Optional createCitationStyleFromFile(final String s return Optional.empty(); } return createCitationStyleFromSource(inputStream, styleFile); - } catch (NoSuchFileException e) { + } catch ( + NoSuchFileException e) { LOGGER.error("Could not find file: {}", styleFile, e); - } catch (IOException e) { + } catch ( + IOException e) { LOGGER.error("Error reading source file", e); } return Optional.empty(); @@ -165,7 +188,9 @@ public static List discoverCitationStyles() { STYLES.addAll(discoverCitationStylesInPath(path)); return STYLES; - } catch (URISyntaxException | IOException e) { + } catch ( + URISyntaxException | + IOException e) { LOGGER.error("something went wrong while searching available CitationStyles", e); return Collections.emptyList(); } @@ -241,22 +266,26 @@ public String getPath() { public boolean isNumericStyle() { try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(new InputSource(new StringReader(source))); - - Element styleElement = doc.getDocumentElement(); - Element infoElement = (Element) styleElement.getElementsByTagName("info").item(0); - Element categoryElement = (Element) infoElement.getElementsByTagName("category").item(0); - - String citationFormat = categoryElement.getAttribute("citation-format"); - return "numeric".equals(citationFormat); - } catch (IOException - | ParserConfigurationException e) { + XMLStreamReader reader = FACTORY.createXMLStreamReader(new StringReader(source)); + + while (reader.hasNext()) { + int event = reader.next(); + + if (event == XMLStreamConstants.START_ELEMENT) { + String elementName = reader.getLocalName(); + + if ("category".equals(elementName)) { + String citationFormat = reader.getAttributeValue(null, "citation-format"); + if (citationFormat != null) { + return "numeric".equals(citationFormat); + } + } + } + } + } catch (XMLStreamException e) { LOGGER.error("Error parsing CSL style XML", e); - return false; - } catch (SAXException e) { - throw new RuntimeException(e); } + + return false; } } diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index c61fc6538e6..6ee2c55c217 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -94,6 +94,7 @@ public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List throws CreationException, IOException, Exception { String style = selectedStyle.getSource(); isNumericStyle = selectedStyle.isNumericStyle(); + System.out.println(isNumericStyle); boolean isAlphanumeric = isAlphanumericStyle(selectedStyle); String inTextCitation; From 9ebff4eee3f6448f5dc248469258736eba25e6d3 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 21:36:59 +0530 Subject: [PATCH 67/94] Fix catch indents --- .../jabref/logic/citationstyle/CitationStyle.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index 5de97b165e3..20aeccac630 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -111,8 +111,7 @@ private static Optional getTitle(String filename, String content) { LOGGER.debug("No valid title or bibliography found for file {}", filename); return Optional.empty(); } - } catch ( - XMLStreamException e) { + } catch (XMLStreamException e) { LOGGER.error("Error parsing XML for file {}: {}", filename, e.getMessage()); return Optional.empty(); } @@ -145,11 +144,9 @@ public static Optional createCitationStyleFromFile(final String s return Optional.empty(); } return createCitationStyleFromSource(inputStream, styleFile); - } catch ( - NoSuchFileException e) { + } catch (NoSuchFileException e) { LOGGER.error("Could not find file: {}", styleFile, e); - } catch ( - IOException e) { + } catch (IOException e) { LOGGER.error("Error reading source file", e); } return Optional.empty(); @@ -188,9 +185,8 @@ public static List discoverCitationStyles() { STYLES.addAll(discoverCitationStylesInPath(path)); return STYLES; - } catch ( - URISyntaxException | - IOException e) { + } catch (URISyntaxException + | IOException e) { LOGGER.error("something went wrong while searching available CitationStyles", e); return Collections.emptyList(); } From 80da1aacfefb14d308721dcd543a32bcb3dbd6e9 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 21:41:10 +0530 Subject: [PATCH 68/94] Mis-leading word --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 6df1d10890b..eb8e5b70ec0 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -952,7 +952,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) } catch (CreationException | WrappedTargetException | com.sun.star.lang.IllegalArgumentException ex) { - LOGGER.warn("Could not create bibliography", ex); + LOGGER.warn("Could not update bibliography", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } } From e479ad4f57a89c81f0f3a4d5ddd55f9bfee181a3 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 21:43:34 +0530 Subject: [PATCH 69/94] Better logs --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index eb8e5b70ec0..65dc650bc78 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -892,7 +892,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) } catch (CreationException | WrappedTargetException | com.sun.star.lang.IllegalArgumentException ex) { - LOGGER.warn("Could not update bibliography", ex); + LOGGER.warn("Could not update JStyle bibliography", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } } else if (style instanceof CitationStyle citationStyle) { @@ -952,7 +952,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) } catch (CreationException | WrappedTargetException | com.sun.star.lang.IllegalArgumentException ex) { - LOGGER.warn("Could not update bibliography", ex); + LOGGER.warn("Could not update CSL bibliography", ex); OOError.fromMisc(ex).setTitle(errorTitle).showErrorDialog(dialogService); } } From b2097086205746851af91ddbbde7009642498392 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 21:52:14 +0530 Subject: [PATCH 70/94] Remove commented code --- .../openoffice/oocsltext/CSLUpdateBibliography.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java index e65dc5a94e7..bf2d0235d07 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java @@ -104,18 +104,6 @@ private static void populateCSLBibTextSection(XTextDocument doc, cslAdapter.insertBibliography(cursor, citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); LOGGER.info("Bibliography inserted using CSLCitationOOAdapter"); - // Remove the initial empty paragraph from the section -// sectionRange = getBibliographyRange(doc); -// if (sectionRange.isPresent()) { -// XTextCursor initialParagraph = doc.getText().createTextCursorByRange(sectionRange.get()); -// initialParagraph.collapseToStart(); -// initialParagraph.goRight((short) 1, true); -// initialParagraph.setString(""); -// LOGGER.info("Initial empty paragraph removed from bibliography section"); -// } else { -// LOGGER.warning("Failed to remove initial empty paragraph: bibliography section not found"); -// } - cursor.collapseToEnd(); LOGGER.info("CSL bibliography section population completed"); } From 39c671fc8a7e8c91c8e06ffcc3db49bdc70445f3 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 22:13:53 +0530 Subject: [PATCH 71/94] Make update bibliography methods non-static --- .../java/org/jabref/gui/openoffice/OOBibBase.java | 5 ++++- .../openoffice/oocsltext/CSLUpdateBibliography.java | 13 +++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 65dc650bc78..2f9f4fc4bfb 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -897,6 +897,9 @@ public void guiActionUpdateDocument(List databases, OOStyle style) } } else if (style instanceof CitationStyle citationStyle) { try { + + CSLUpdateBibliography cslUpdateBibliography = new CSLUpdateBibliography(); + OOResult odoc = getXTextDocument(); if (testDialog(errorTitle, odoc.asVoidResult())) { return; @@ -940,7 +943,7 @@ public void guiActionUpdateDocument(List databases, OOStyle style) BibDatabase bibDatabase = new BibDatabase(citedEntries); BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(bibDatabase); - CSLUpdateBibliography.rebuildCSLBibliography(doc, cslCitationOOAdapter, citedEntries, citationStyle, bibDatabaseContext, Injector.instantiateModelOrService(BibEntryTypesManager.class)); + cslUpdateBibliography.rebuildCSLBibliography(doc, cslCitationOOAdapter, citedEntries, citationStyle, bibDatabaseContext, Injector.instantiateModelOrService(BibEntryTypesManager.class)); } catch (NoDocumentException | NoSuchElementException e) { diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java index bf2d0235d07..bb4f1c05555 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java @@ -23,10 +23,7 @@ public class CSLUpdateBibliography { private static final String CSL_BIB_SECTION_NAME = "CSL_bibliography"; private static final Logger LOGGER = Logger.getLogger(CSLUpdateBibliography.class.getName()); - private CSLUpdateBibliography() { - } - - public static Optional getBibliographyRange(XTextDocument doc) + public Optional getBibliographyRange(XTextDocument doc) throws NoDocumentException, WrappedTargetException { LOGGER.info("Attempting to get bibliography range"); Optional range = UnoTextSection.getAnchor(doc, CSL_BIB_SECTION_NAME); @@ -37,7 +34,7 @@ public static Optional getBibliographyRange(XTextDocument doc) /** * Rebuilds the bibliography using CSL. */ - public static void rebuildCSLBibliography(XTextDocument doc, + public void rebuildCSLBibliography(XTextDocument doc, CSLCitationOOAdapter cslAdapter, List entries, CitationStyle citationStyle, @@ -60,7 +57,7 @@ public static void rebuildCSLBibliography(XTextDocument doc, LOGGER.info("Finished rebuilding CSL bibliography"); } - private static void createCSLBibTextSection(XTextDocument doc) + private void createCSLBibTextSection(XTextDocument doc) throws CreationException { LOGGER.info("Creating new CSL bibliography section"); XTextCursor textCursor = doc.getText().createTextCursor(); @@ -70,7 +67,7 @@ private static void createCSLBibTextSection(XTextDocument doc) LOGGER.info("CSL bibliography section created"); } - private static void clearCSLBibTextSectionContent(XTextDocument doc) + private void clearCSLBibTextSectionContent(XTextDocument doc) throws NoDocumentException, WrappedTargetException { LOGGER.info("Clearing CSL bibliography section content"); Optional sectionRange = getBibliographyRange(doc); @@ -83,7 +80,7 @@ private static void clearCSLBibTextSectionContent(XTextDocument doc) } } - private static void populateCSLBibTextSection(XTextDocument doc, + private void populateCSLBibTextSection(XTextDocument doc, CSLCitationOOAdapter cslAdapter, List entries, CitationStyle citationStyle, From 3e37e665abbac7cb2a24e3b2b9910529ff3f3295 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 22:22:28 +0530 Subject: [PATCH 72/94] Fix log level & use slf4 logger --- .../oocsltext/CSLUpdateBibliography.java | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java index bb4f1c05555..21cb87b6cf6 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLUpdateBibliography.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.Optional; -import java.util.logging.Logger; import org.jabref.logic.citationstyle.CitationStyle; import org.jabref.model.database.BibDatabaseContext; @@ -17,17 +16,19 @@ import com.sun.star.text.XTextCursor; import com.sun.star.text.XTextDocument; import com.sun.star.text.XTextRange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class CSLUpdateBibliography { private static final String CSL_BIB_SECTION_NAME = "CSL_bibliography"; - private static final Logger LOGGER = Logger.getLogger(CSLUpdateBibliography.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(CSLUpdateBibliography.class); public Optional getBibliographyRange(XTextDocument doc) throws NoDocumentException, WrappedTargetException { - LOGGER.info("Attempting to get bibliography range"); + LOGGER.debug("Attempting to get bibliography range"); Optional range = UnoTextSection.getAnchor(doc, CSL_BIB_SECTION_NAME); - LOGGER.info("Bibliography range found: " + range.isPresent()); + LOGGER.debug("Bibliography range found: {}", range.isPresent()); return range; } @@ -35,63 +36,63 @@ public Optional getBibliographyRange(XTextDocument doc) * Rebuilds the bibliography using CSL. */ public void rebuildCSLBibliography(XTextDocument doc, - CSLCitationOOAdapter cslAdapter, - List entries, - CitationStyle citationStyle, - BibDatabaseContext bibDatabaseContext, - BibEntryTypesManager bibEntryTypesManager) + CSLCitationOOAdapter cslAdapter, + List entries, + CitationStyle citationStyle, + BibDatabaseContext bibDatabaseContext, + BibEntryTypesManager bibEntryTypesManager) throws WrappedTargetException, NoDocumentException, CreationException { - LOGGER.info("Starting to rebuild CSL bibliography"); + LOGGER.debug("Starting to rebuild CSL bibliography"); // Ensure the bibliography section exists Optional sectionRange = getBibliographyRange(doc); if (sectionRange.isEmpty()) { - LOGGER.info("Bibliography section not found. Creating new section."); + LOGGER.debug("Bibliography section not found. Creating new section."); createCSLBibTextSection(doc); } else { - LOGGER.info("Bibliography section found. Clearing content."); + LOGGER.debug("Bibliography section found. Clearing content."); clearCSLBibTextSectionContent(doc); } populateCSLBibTextSection(doc, cslAdapter, entries, citationStyle, bibDatabaseContext, bibEntryTypesManager); - LOGGER.info("Finished rebuilding CSL bibliography"); + LOGGER.debug("Finished rebuilding CSL bibliography"); } private void createCSLBibTextSection(XTextDocument doc) throws CreationException { - LOGGER.info("Creating new CSL bibliography section"); + LOGGER.debug("Creating new CSL bibliography section"); XTextCursor textCursor = doc.getText().createTextCursor(); textCursor.gotoEnd(false); DocumentAnnotation annotation = new DocumentAnnotation(doc, CSL_BIB_SECTION_NAME, textCursor, false); UnoTextSection.create(annotation); - LOGGER.info("CSL bibliography section created"); + LOGGER.debug("CSL bibliography section created"); } private void clearCSLBibTextSectionContent(XTextDocument doc) throws NoDocumentException, WrappedTargetException { - LOGGER.info("Clearing CSL bibliography section content"); + LOGGER.debug("Clearing CSL bibliography section content"); Optional sectionRange = getBibliographyRange(doc); if (sectionRange.isPresent()) { XTextCursor cursor = doc.getText().createTextCursorByRange(sectionRange.get()); cursor.setString(""); - LOGGER.info("CSL bibliography section content cleared"); + LOGGER.debug("CSL bibliography section content cleared"); } else { - LOGGER.warning("Failed to clear CSL bibliography section: section not found"); + LOGGER.warn("Failed to clear CSL bibliography section: section not found"); } } private void populateCSLBibTextSection(XTextDocument doc, - CSLCitationOOAdapter cslAdapter, - List entries, - CitationStyle citationStyle, - BibDatabaseContext bibDatabaseContext, - BibEntryTypesManager bibEntryTypesManager) + CSLCitationOOAdapter cslAdapter, + List entries, + CitationStyle citationStyle, + BibDatabaseContext bibDatabaseContext, + BibEntryTypesManager bibEntryTypesManager) throws WrappedTargetException, NoDocumentException, CreationException { - LOGGER.info("Populating CSL bibliography section"); + LOGGER.debug("Populating CSL bibliography section"); Optional sectionRange = getBibliographyRange(doc); if (sectionRange.isEmpty()) { - LOGGER.severe("Bibliography section not found when trying to populate"); + LOGGER.error("Bibliography section not found when trying to populate"); throw new IllegalStateException("Bibliography section not found"); } @@ -99,9 +100,9 @@ private void populateCSLBibTextSection(XTextDocument doc, // Use CSLCitationOOAdapter to insert the bibliography cslAdapter.insertBibliography(cursor, citationStyle, entries, bibDatabaseContext, bibEntryTypesManager); - LOGGER.info("Bibliography inserted using CSLCitationOOAdapter"); + LOGGER.debug("Bibliography inserted using CSLCitationOOAdapter"); cursor.collapseToEnd(); - LOGGER.info("CSL bibliography section population completed"); + LOGGER.debug("CSL bibliography section population completed"); } } From 5392ee76c24918835cfb15a56cf64e9ecf99397d Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 22:53:23 +0530 Subject: [PATCH 73/94] Field conversion - numeric style detection --- .../logic/citationstyle/CitationStyle.java | 67 +++++++++++-------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index 20aeccac630..af434694ab5 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -44,11 +44,13 @@ public class CitationStyle implements OOStyle { private final String filePath; private final String title; + private final boolean isNumericStyle; private final String source; - private CitationStyle(final String filename, final String title, final String source) { + private CitationStyle(final String filename, final String title, final boolean isNumericStyle, final String source) { this.filePath = Objects.requireNonNull(filename); this.title = Objects.requireNonNull(title); + this.isNumericStyle = isNumericStyle; this.source = Objects.requireNonNull(source); } @@ -67,7 +69,9 @@ private static Optional createCitationStyleFromSource(final Input return Optional.empty(); } - return Optional.of(new CitationStyle(filename, title.get(), content)); + boolean isNumericStyle = isNumericStyle(filename, content); + + return Optional.of(new CitationStyle(filename, title.get(), isNumericStyle, content)); } catch (NullPointerException | IOException e) { LOGGER.error("Error while parsing source", e); @@ -117,6 +121,34 @@ private static Optional getTitle(String filename, String content) { } } + private static boolean isNumericStyle(String filename, String content) { + FACTORY.setProperty(XMLInputFactory.IS_COALESCING, true); + + try { + XMLStreamReader reader = FACTORY.createXMLStreamReader(new StringReader(content)); + + while (reader.hasNext()) { + int event = reader.next(); + + if (event == XMLStreamConstants.START_ELEMENT) { + String elementName = reader.getLocalName(); + + if ("category".equals(elementName)) { + String citationFormat = reader.getAttributeValue(null, "citation-format"); + if (citationFormat != null) { + return "numeric".equals(citationFormat); + } + } + } + } + } catch (XMLStreamException e) { + LOGGER.error("Error parsing CSL style XML for file {}: {}", filename, e.getMessage()); + } + + LOGGER.warn("Cannot determine if {} is a numeric style!", filename); + return false; + } + private static String stripInvalidProlog(String source) { int startIndex = source.indexOf("<"); if (startIndex > 0) { @@ -158,7 +190,7 @@ public static Optional createCitationStyleFromFile(final String s * @return default citation style */ public static CitationStyle getDefault() { - return createCitationStyleFromFile(DEFAULT).orElse(new CitationStyle("", "Empty", "")); + return createCitationStyleFromFile(DEFAULT).orElse(new CitationStyle("", "Empty", false, "")); } /** @@ -214,6 +246,10 @@ public String getTitle() { return title; } + public boolean isNumericStyle() { + return isNumericStyle; + } + public String getSource() { return source; } @@ -259,29 +295,4 @@ public boolean isInternalStyle() { public String getPath() { return getFilePath(); } - - public boolean isNumericStyle() { - try { - XMLStreamReader reader = FACTORY.createXMLStreamReader(new StringReader(source)); - - while (reader.hasNext()) { - int event = reader.next(); - - if (event == XMLStreamConstants.START_ELEMENT) { - String elementName = reader.getLocalName(); - - if ("category".equals(elementName)) { - String citationFormat = reader.getAttributeValue(null, "citation-format"); - if (citationFormat != null) { - return "numeric".equals(citationFormat); - } - } - } - } - } catch (XMLStreamException e) { - LOGGER.error("Error parsing CSL style XML", e); - } - - return false; - } } From 8b7b8803137f6f6e89ed0faa3c789c22e7e02223 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 23:03:36 +0530 Subject: [PATCH 74/94] Collapse XML parsing of title and isNumericStyle, use record type --- .../logic/citationstyle/CitationStyle.java | 72 +++++++------------ .../oocsltext/CSLCitationOOAdapter.java | 13 ++-- 2 files changed, 29 insertions(+), 56 deletions(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index af434694ab5..c946e1370fb 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -59,27 +59,24 @@ private CitationStyle(final String filename, final String title, final boolean i */ private static Optional createCitationStyleFromSource(final InputStream source, final String filename) { try { - // We need the content twice: - // First, for parsing it here for the name - // Second for the CSL library to parse it String content = new String(source.readAllBytes()); - Optional title = getTitle(filename, content); - if (title.isEmpty()) { + Optional styleInfo = parseStyleInfo(filename, content); + if (styleInfo.isEmpty()) { return Optional.empty(); } - boolean isNumericStyle = isNumericStyle(filename, content); - - return Optional.of(new CitationStyle(filename, title.get(), isNumericStyle, content)); - } catch (NullPointerException - | IOException e) { + return Optional.of(new CitationStyle(filename, styleInfo.get().title(), styleInfo.get().isNumericStyle(), content)); + } catch (NullPointerException | IOException e) { LOGGER.error("Error while parsing source", e); return Optional.empty(); } } - private static Optional getTitle(String filename, String content) { + public record StyleInfo(String title, boolean isNumericStyle) { + } + + private static Optional parseStyleInfo(String filename, String content) { FACTORY.setProperty(XMLInputFactory.IS_COALESCING, true); try { @@ -87,7 +84,8 @@ private static Optional getTitle(String filename, String content) { boolean inInfo = false; boolean hasBibliography = false; - String title = ""; + String title = null; + boolean isNumericStyle = false; while (reader.hasNext()) { int event = reader.next(); @@ -95,12 +93,20 @@ private static Optional getTitle(String filename, String content) { if (event == XMLStreamConstants.START_ELEMENT) { String elementName = reader.getLocalName(); - if ("bibliography".equals(elementName)) { - hasBibliography = true; - } else if ("info".equals(elementName)) { - inInfo = true; - } else if (inInfo && "title".equals(elementName)) { - title = reader.getElementText(); + switch (elementName) { + case "bibliography" -> hasBibliography = true; + case "info" -> inInfo = true; + case "title" -> { + if (inInfo) { + title = reader.getElementText(); + } + } + case "category" -> { + String citationFormat = reader.getAttributeValue(null, "citation-format"); + if (citationFormat != null) { + isNumericStyle = "numeric".equals(citationFormat); + } + } } } else if (event == XMLStreamConstants.END_ELEMENT) { if ("info".equals(reader.getLocalName())) { @@ -110,7 +116,7 @@ private static Optional getTitle(String filename, String content) { } if (hasBibliography && title != null) { - return Optional.of(title); + return Optional.of(new StyleInfo(title, isNumericStyle)); } else { LOGGER.debug("No valid title or bibliography found for file {}", filename); return Optional.empty(); @@ -121,34 +127,6 @@ private static Optional getTitle(String filename, String content) { } } - private static boolean isNumericStyle(String filename, String content) { - FACTORY.setProperty(XMLInputFactory.IS_COALESCING, true); - - try { - XMLStreamReader reader = FACTORY.createXMLStreamReader(new StringReader(content)); - - while (reader.hasNext()) { - int event = reader.next(); - - if (event == XMLStreamConstants.START_ELEMENT) { - String elementName = reader.getLocalName(); - - if ("category".equals(elementName)) { - String citationFormat = reader.getAttributeValue(null, "citation-format"); - if (citationFormat != null) { - return "numeric".equals(citationFormat); - } - } - } - } - } catch (XMLStreamException e) { - LOGGER.error("Error parsing CSL style XML for file {}: {}", filename, e.getMessage()); - } - - LOGGER.warn("Cannot determine if {} is a numeric style!", filename); - return false; - } - private static String stripInvalidProlog(String source) { int startIndex = source.indexOf("<"); if (startIndex > 0) { diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 6ee2c55c217..71bffc71332 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -41,7 +41,6 @@ public class CSLCitationOOAdapter { private final CitationStyleOutputFormat format = CitationStyleOutputFormat.HTML; private final XTextDocument document; private final CSLReferenceMarkManager markManager; - private boolean isNumericStyle = false; public CSLCitationOOAdapter(XTextDocument doc) { this.document = doc; @@ -61,7 +60,6 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, OOTextIntoOO.write(document, cursor, ooBreak); String style = selectedStyle.getSource(); - isNumericStyle = selectedStyle.isNumericStyle(); // Sort entries based on their order of appearance in the document entries.sort(Comparator.comparingInt(entry -> markManager.getCitationNumber(entry.getCitationKey().orElse("")))); @@ -72,7 +70,7 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, System.out.println(citation); String formattedCitation; - if (isNumericStyle) { + if (selectedStyle.isNumericStyle()) { formattedCitation = updateSingleCitation(transformHtml(citation), currentNumber); } else { formattedCitation = transformHtml(citation); @@ -80,7 +78,7 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, OOText ooText = OOFormat.setLocaleNone(OOText.fromString(formattedCitation)); OOTextIntoOO.write(document, cursor, ooText); - if (isNumericStyle) { + if (selectedStyle.isNumericStyle()) { // Select the paragraph break cursor.goLeft((short) 1, true); @@ -93,8 +91,6 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws CreationException, IOException, Exception { String style = selectedStyle.getSource(); - isNumericStyle = selectedStyle.isNumericStyle(); - System.out.println(isNumericStyle); boolean isAlphanumeric = isAlphanumericStyle(selectedStyle); String inTextCitation; @@ -106,7 +102,7 @@ public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List String formattedCitation = transformHtml(inTextCitation); - if (isNumericStyle) { + if (selectedStyle.isNumericStyle()) { formattedCitation = updateMultipleCitations(formattedCitation, entries); } @@ -124,7 +120,6 @@ public void insertCitation(XTextCursor cursor, CitationStyle selectedStyle, List public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle, List entries, BibDatabaseContext bibDatabaseContext, BibEntryTypesManager bibEntryTypesManager) throws IOException, CreationException, Exception { String style = selectedStyle.getSource(); - isNumericStyle = selectedStyle.isNumericStyle(); boolean isAlphanumeric = isAlphanumericStyle(selectedStyle); Iterator iterator = entries.iterator(); @@ -146,7 +141,7 @@ public void insertInTextCitation(XTextCursor cursor, CitationStyle selectedStyle } String formattedCitation = transformHtml(inTextCitation); String finalText; - if (isNumericStyle) { + if (selectedStyle.isNumericStyle()) { formattedCitation = updateMultipleCitations(formattedCitation, List.of(currentEntry)); String prefix = currentEntry.getResolvedFieldOrAlias(StandardField.AUTHOR, bibDatabaseContext.getDatabase()) .map(AuthorList::parse) From 98b9218e1fe1ac5530c29f05f4579ec82336f8d9 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 23:05:40 +0530 Subject: [PATCH 75/94] Avoid nulls --- src/main/java/org/jabref/logic/citationstyle/CitationStyle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index c946e1370fb..aabc05f3546 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -84,7 +84,7 @@ private static Optional parseStyleInfo(String filename, String conten boolean inInfo = false; boolean hasBibliography = false; - String title = null; + String title = ""; boolean isNumericStyle = false; while (reader.hasNext()) { From 164ef092dfa1ddc489420d675d321aa56094e047 Mon Sep 17 00:00:00 2001 From: subhramit Date: Sun, 11 Aug 2024 23:09:28 +0530 Subject: [PATCH 76/94] No NPE needed --- src/main/java/org/jabref/logic/citationstyle/CitationStyle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java index aabc05f3546..61d15761158 100644 --- a/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java +++ b/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java @@ -67,7 +67,7 @@ private static Optional createCitationStyleFromSource(final Input } return Optional.of(new CitationStyle(filename, styleInfo.get().title(), styleInfo.get().isNumericStyle(), content)); - } catch (NullPointerException | IOException e) { + } catch (IOException e) { LOGGER.error("Error while parsing source", e); return Optional.empty(); } From 18f10b4f444b990e5be95ddb74686543de675f62 Mon Sep 17 00:00:00 2001 From: subhramit Date: Mon, 12 Aug 2024 00:14:54 +0530 Subject: [PATCH 77/94] Fix submodules --- src/main/resources/csl-styles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index bf2926b71a9..df939b87950 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit bf2926b71a969644ce735760977d1246aed1f2e2 +Subproject commit df939b87950c9f22a98e7a8188bbeabbc307bb42 From 254bc634c726bc6edc3d7e655750d8e5ed7193a3 Mon Sep 17 00:00:00 2001 From: subhramit Date: Mon, 12 Aug 2024 00:47:07 +0530 Subject: [PATCH 78/94] Change make bibliography icon --- src/main/resources/csl-styles | 2 +- .../resources/fonts/JabRefMaterialDesign.ttf | Bin 8756 -> 8792 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index df939b87950..bf2926b71a9 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit df939b87950c9f22a98e7a8188bbeabbc307bb42 +Subproject commit bf2926b71a969644ce735760977d1246aed1f2e2 diff --git a/src/main/resources/fonts/JabRefMaterialDesign.ttf b/src/main/resources/fonts/JabRefMaterialDesign.ttf index fb5b40fb76b9c53a2bb08fe4b50539a98fade7e3..6d62e382fee15773999973f2a5f296a60c124e52 100644 GIT binary patch delta 364 zcmdnua>HeUL;X6}j0p@3j1>$FvQsir6H_$q?BB(}AkV|Vz+jdE6ktEZd;`dL0rFKc za!V?LfD9l%14zW=SF%!&cZ$sYmo4RRAJ3K--WcL4ccfP96##N5=lHJT5BOc4eK zCZ&S>;t~dCpbUeO1xTKOnR(;>IkNThm=7>WGRQJ0F=#LtGgvY(s46R|nF^Yi87mrz z$ujCODl4(En<@$#vx_n-f@pJ7AO$2uS=H5)_!-5`%}mr8jTzM$MHyFLQ#LYEW(rd_ z;u7KJ5###1>K01_>FjGoLRf0*&q<_q#EOaPlvT6X{d delta 328 zcmccNvc+YBL;c3C&g~2gj1>$FvIQBbi76VFb& zq*Rb!T*AN%lwnX30m(BkGjH5KN4CC!`2Yh811AF?gD8U{1JF1|Q$}=`OpQStQ(+@9Q9}_nenyaxIZ%XAn<@0~Y8YOv9j2|_&;TU3_=H$k-2)oJ!V(x8 zLPP&EgoZK!v37&@>VH72EvhYQ#HcOI%f`dvrL7U64RjYH1S^Hg Date: Mon, 12 Aug 2024 02:45:03 +0530 Subject: [PATCH 79/94] Fix submodules --- src/main/resources/csl-styles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index bf2926b71a9..df939b87950 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit bf2926b71a969644ce735760977d1246aed1f2e2 +Subproject commit df939b87950c9f22a98e7a8188bbeabbc307bb42 From b967f952ba548938eafa9c4505fb991013910563 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:19:24 +0000 Subject: [PATCH 80/94] Bump org.hamcrest:hamcrest-library from 2.2 to 3.0 (#11607) Bumps [org.hamcrest:hamcrest-library](https://github.com/hamcrest/JavaHamcrest) from 2.2 to 3.0. - [Release notes](https://github.com/hamcrest/JavaHamcrest/releases) - [Changelog](https://github.com/hamcrest/JavaHamcrest/blob/master/CHANGES.md) - [Commits](https://github.com/hamcrest/JavaHamcrest/compare/v2.2...v3.0) --- updated-dependencies: - dependency-name: org.hamcrest:hamcrest-library dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c866f245365..6ce435ea79d 100644 --- a/build.gradle +++ b/build.gradle @@ -324,7 +324,7 @@ dependencies { testImplementation 'com.tngtech.archunit:archunit-junit5-api:1.3.0' testImplementation "org.testfx:testfx-core:4.0.16-alpha" testImplementation "org.testfx:testfx-junit5:4.0.16-alpha" - testImplementation "org.hamcrest:hamcrest-library:2.2" + testImplementation "org.hamcrest:hamcrest-library:3.0" checkstyle 'com.puppycrawl.tools:checkstyle:10.17.0' // xjc needs the runtime as well for the ant task, otherwise it fails From 69a1e311212c04bb257b950888d63fb7ea883687 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:33:43 +0000 Subject: [PATCH 81/94] Bump org.glassfish.jersey.inject:jersey-hk2 from 3.1.7 to 3.1.8 (#11609) Bumps org.glassfish.jersey.inject:jersey-hk2 from 3.1.7 to 3.1.8. --- updated-dependencies: - dependency-name: org.glassfish.jersey.inject:jersey-hk2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6ce435ea79d..fee30c96ded 100644 --- a/build.gradle +++ b/build.gradle @@ -287,7 +287,7 @@ dependencies { // Implementation of the API implementation 'org.glassfish.jersey.core:jersey-server:3.1.7' // injection framework - implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.7' + implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.8' implementation 'org.glassfish.hk2:hk2-api:3.1.1' // testImplementation 'org.glassfish.hk2:hk2-testing:3.0.4' // implementation 'org.glassfish.hk2:hk2-testing-jersey:3.0.4' From 4acf2af92660272d81770cdf772f007fd6abff91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 14:36:11 +0000 Subject: [PATCH 82/94] Bump org.slf4j:slf4j-api from 2.0.13 to 2.0.16 (#11610) Bumps org.slf4j:slf4j-api from 2.0.13 to 2.0.16. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index fee30c96ded..e3e80e6b8a0 100644 --- a/build.gradle +++ b/build.gradle @@ -248,7 +248,7 @@ dependencies { implementation 'com.konghq:unirest-modules-gson:4.4.4' implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1' - implementation 'org.slf4j:slf4j-api:2.0.13' + implementation 'org.slf4j:slf4j-api:2.0.16' implementation 'org.tinylog:tinylog-api:2.7.0' implementation 'org.tinylog:slf4j-tinylog:2.7.0' implementation 'org.tinylog:tinylog-impl:2.7.0' From 0f98fae6db29bdd209dc8824412007ea44ae5cb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:20:41 +0000 Subject: [PATCH 83/94] Bump pdfbox from 3.0.2 to 3.0.3 (#11606) Bumps `pdfbox` from 3.0.2 to 3.0.3. Updates `org.apache.pdfbox:pdfbox` from 3.0.2 to 3.0.3 Updates `org.apache.pdfbox:fontbox` from 3.0.2 to 3.0.3 Updates `org.apache.pdfbox:xmpbox` from 3.0.2 to 3.0.3 --- updated-dependencies: - dependency-name: org.apache.pdfbox:pdfbox dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.pdfbox:fontbox dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.pdfbox:xmpbox dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e3e80e6b8a0..2fd1cb09795 100644 --- a/build.gradle +++ b/build.gradle @@ -149,7 +149,7 @@ dependencies { // Include all jar-files in the 'lib' folder as dependencies implementation fileTree(dir: 'lib', includes: ['*.jar']) - def pdfbox = "3.0.2" + def pdfbox = "3.0.3" implementation ("org.apache.pdfbox:pdfbox:$pdfbox") { exclude group: 'commons-logging' } From 8a56c646e2a0c6b457c6a32712ef6ee4054f9d9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:24:05 +0000 Subject: [PATCH 84/94] Bump src/main/resources/csl-locales from `e631a52` to `242640a` (#11612) Bumps [src/main/resources/csl-locales](https://github.com/citation-style-language/locales) from `e631a52` to `242640a`. - [Release notes](https://github.com/citation-style-language/locales/releases) - [Commits](https://github.com/citation-style-language/locales/compare/e631a52dcea396be20d031b6456e91dba7772224...242640a0e00972f48c417530f9c2b9518504c0b6) --- updated-dependencies: - dependency-name: src/main/resources/csl-locales dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/main/resources/csl-locales | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/csl-locales b/src/main/resources/csl-locales index e631a52dcea..242640a0e00 160000 --- a/src/main/resources/csl-locales +++ b/src/main/resources/csl-locales @@ -1 +1 @@ -Subproject commit e631a52dcea396be20d031b6456e91dba7772224 +Subproject commit 242640a0e00972f48c417530f9c2b9518504c0b6 From 119d088c1a867d6ec60bfbc2b5167b0b2907fe77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:25:07 +0000 Subject: [PATCH 85/94] Bump src/main/resources/csl-styles from `df939b8` to `d9989a2` (#11613) Bumps [src/main/resources/csl-styles](https://github.com/citation-style-language/styles) from `df939b8` to `d9989a2`. - [Release notes](https://github.com/citation-style-language/styles/releases) - [Commits](https://github.com/citation-style-language/styles/compare/df939b87950c9f22a98e7a8188bbeabbc307bb42...d9989a28ed474d87dbb600fc233fb37e773b59a8) --- updated-dependencies: - dependency-name: src/main/resources/csl-styles dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/main/resources/csl-styles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/csl-styles b/src/main/resources/csl-styles index df939b87950..d9989a28ed4 160000 --- a/src/main/resources/csl-styles +++ b/src/main/resources/csl-styles @@ -1 +1 @@ -Subproject commit df939b87950c9f22a98e7a8188bbeabbc307bb42 +Subproject commit d9989a28ed474d87dbb600fc233fb37e773b59a8 From 91876e3af8fc471ec72bfcd11edc6fb5374696fd Mon Sep 17 00:00:00 2001 From: subhramit Date: Tue, 13 Aug 2024 00:31:06 +0530 Subject: [PATCH 86/94] Add reference to authorsAlpha, better method name --- .../openoffice/oocsltext/CSLCitationOOAdapter.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 71bffc71332..24f2b57e4a6 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -321,7 +321,7 @@ private String generateAlphanumericCitation(List entries, BibDatabaseC if (author.isPresent() && year.isPresent()) { AuthorList authorList = AuthorList.parse(author.get()); - String alphaKey = authorsAlpha(authorList); + String alphaKey = authorRepresentationExtractor(authorList); // Extract last two digits of the year String shortYear = year.get().length() >= 2 ? @@ -345,7 +345,13 @@ private boolean isAlphanumericStyle(CitationStyle style) { return "DIN 1505-2 (alphanumeric, Deutsch) - standard superseded by ISO-690".equals(style.getTitle()); } - public static String authorsAlpha(AuthorList authorList) { + /** + * Adapted from {@link BracketedPattern#authorsAlpha(AuthorList) authorsAlpha} + * + * @param authorList - list of authors to generate alphabetic representation for. + * @return first four letters of the author (in case of a single author), first letter of each author till 4 authors, in case of multiple authors. + */ + public static String authorRepresentationExtractor(AuthorList authorList) { StringBuilder alphaStyle = new StringBuilder(); int maxAuthors = Math.min(authorList.getNumberOfAuthors(), MAX_ALPHA_AUTHORS); From 3c86db30c92e1c6480f4b9cc5481eae71bf9d1f4 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 12 Aug 2024 21:17:46 +0200 Subject: [PATCH 87/94] Add more tests --- .../jabref/logic/citationkeypattern/BracketedPatternTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java b/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java index f2893707f0e..4202153415c 100644 --- a/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java +++ b/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java @@ -80,6 +80,9 @@ static Stream authorsAlpha() { Arguments.of("A+", "Aachen and others"), Arguments.of("AB+", "Aachen and Berlin and others"), Arguments.of("ABC+", "Aachen and Berlin and Chemnitz and others"), + // FIXME: Arguments.of("Aach", "Aachen"), + Arguments.of("AB", "Aachen and Berlin"), + Arguments.of("ABC", "Aachen and Berlin and Chemnitz"), Arguments.of("ABCD", "Aachen and Berlin and Chemnitz and Düsseldorf"), Arguments.of("ABC+", "Aachen and Berlin and Chemnitz and Düsseldorf and others"), Arguments.of("ABC+", "Aachen and Berlin and Chemnitz and Düsseldorf and Essen"), From 13d94f5afa2feb51bb890f49a297f18acc2756fe Mon Sep 17 00:00:00 2001 From: subhramit Date: Tue, 13 Aug 2024 00:47:49 +0530 Subject: [PATCH 88/94] Use original authorsAlpha --- .../oocsltext/CSLCitationOOAdapter.java | 46 ++----------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 24f2b57e4a6..239e68b64a7 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -13,7 +13,6 @@ import org.jabref.logic.citationstyle.CitationStyleGenerator; import org.jabref.logic.citationstyle.CitationStyleOutputFormat; import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.entry.Author; import org.jabref.model.entry.AuthorList; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.BibEntryTypesManager; @@ -30,6 +29,8 @@ import com.sun.star.uno.Exception; import org.apache.commons.text.StringEscapeUtils; +import static org.jabref.logic.citationkeypattern.BracketedPattern.authorsAlpha; + public class CSLCitationOOAdapter { // TODO: These are static final fields right now, should add the functionality to let user select these and store them in preferences. @@ -321,7 +322,7 @@ private String generateAlphanumericCitation(List entries, BibDatabaseC if (author.isPresent() && year.isPresent()) { AuthorList authorList = AuthorList.parse(author.get()); - String alphaKey = authorRepresentationExtractor(authorList); + String alphaKey = authorsAlpha(authorList); // Extract last two digits of the year String shortYear = year.get().length() >= 2 ? @@ -345,45 +346,4 @@ private boolean isAlphanumericStyle(CitationStyle style) { return "DIN 1505-2 (alphanumeric, Deutsch) - standard superseded by ISO-690".equals(style.getTitle()); } - /** - * Adapted from {@link BracketedPattern#authorsAlpha(AuthorList) authorsAlpha} - * - * @param authorList - list of authors to generate alphabetic representation for. - * @return first four letters of the author (in case of a single author), first letter of each author till 4 authors, in case of multiple authors. - */ - public static String authorRepresentationExtractor(AuthorList authorList) { - StringBuilder alphaStyle = new StringBuilder(); - int maxAuthors = Math.min(authorList.getNumberOfAuthors(), MAX_ALPHA_AUTHORS); - - if (authorList.getNumberOfAuthors() == 1) { - String[] firstAuthor = authorList.getAuthor(0).getNamePrefixAndFamilyName() - .replaceAll("\\s+", " ").trim().split(" "); - // take first letter of any "prefixes" (e.g. van der Aalst -> vd) - for (int j = 0; j < (firstAuthor.length - 1); j++) { - alphaStyle.append(firstAuthor[j], 0, 1); - } - // append last part of last name completely - alphaStyle.append(firstAuthor[firstAuthor.length - 1], 0, - Math.min(4, firstAuthor[firstAuthor.length - 1].length())); - } else { - boolean andOthersPresent = authorList.getAuthor(maxAuthors - 1).equals(Author.OTHERS); - if (andOthersPresent) { - maxAuthors--; - } - List vonAndLastNames = authorList.getAuthors().stream() - .limit(maxAuthors) - .map(Author::getNamePrefixAndFamilyName) - .toList(); - for (String vonAndLast : vonAndLastNames) { - // replace all whitespaces by " " - // split the lastname at " " - String[] nameParts = vonAndLast.replaceAll("\\s+", " ").trim().split(" "); - for (String part : nameParts) { - // use first character of each part of lastname - alphaStyle.append(part, 0, 1); - } - } - } - return alphaStyle.toString(); - } } From 50b005868e3a527366ac2cc92dbe4794e76eb481 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 12 Aug 2024 21:40:14 +0200 Subject: [PATCH 89/94] Remove static import --- .../logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 239e68b64a7..0f8c6fc3e51 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -29,8 +29,6 @@ import com.sun.star.uno.Exception; import org.apache.commons.text.StringEscapeUtils; -import static org.jabref.logic.citationkeypattern.BracketedPattern.authorsAlpha; - public class CSLCitationOOAdapter { // TODO: These are static final fields right now, should add the functionality to let user select these and store them in preferences. @@ -322,7 +320,7 @@ private String generateAlphanumericCitation(List entries, BibDatabaseC if (author.isPresent() && year.isPresent()) { AuthorList authorList = AuthorList.parse(author.get()); - String alphaKey = authorsAlpha(authorList); + String alphaKey = BracketedPattern.authorsAlpha(authorList); // Extract last two digits of the year String shortYear = year.get().length() >= 2 ? From b81444f392c290b489979a507fb8782a3f82be96 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 12 Aug 2024 21:41:59 +0200 Subject: [PATCH 90/94] Discard changes to src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java --- .../jabref/logic/citationkeypattern/BracketedPatternTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java b/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java index 4202153415c..f2893707f0e 100644 --- a/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java +++ b/src/test/java/org/jabref/logic/citationkeypattern/BracketedPatternTest.java @@ -80,9 +80,6 @@ static Stream authorsAlpha() { Arguments.of("A+", "Aachen and others"), Arguments.of("AB+", "Aachen and Berlin and others"), Arguments.of("ABC+", "Aachen and Berlin and Chemnitz and others"), - // FIXME: Arguments.of("Aach", "Aachen"), - Arguments.of("AB", "Aachen and Berlin"), - Arguments.of("ABC", "Aachen and Berlin and Chemnitz"), Arguments.of("ABCD", "Aachen and Berlin and Chemnitz and Düsseldorf"), Arguments.of("ABC+", "Aachen and Berlin and Chemnitz and Düsseldorf and others"), Arguments.of("ABC+", "Aachen and Berlin and Chemnitz and Düsseldorf and Essen"), From c1060bb9c2daed4a63a73874ee68268900568b6a Mon Sep 17 00:00:00 2001 From: subhramit Date: Tue, 13 Aug 2024 01:13:13 +0530 Subject: [PATCH 91/94] Fix extra newline --- .../jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 0f8c6fc3e51..08dee193f91 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -343,5 +343,4 @@ private String generateAlphanumericCitation(List entries, BibDatabaseC private boolean isAlphanumericStyle(CitationStyle style) { return "DIN 1505-2 (alphanumeric, Deutsch) - standard superseded by ISO-690".equals(style.getTitle()); } - } From daa2f3b89212c698985442ae28b645418c9c753c Mon Sep 17 00:00:00 2001 From: Christoph Date: Mon, 12 Aug 2024 22:02:27 +0200 Subject: [PATCH 92/94] Remove comment on PR again (#11615) --- .github/workflows/tests.yml | 61 +------------------------------------ 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 84e0197456d..73881d4b843 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,10 +5,9 @@ on: branches: - main - main-release + pull_request: merge_group: workflow_dispatch: - # The checkers should write comments on the PR if something fails. For this, we need to have a proper GITHUB_TOKEN. This is enabled by ..._target. - pull_request_target: env: SpringerNatureAPIKey: ${{ secrets.SpringerNatureAPIKey }} @@ -52,21 +51,8 @@ jobs: gradle-home-cache-cleanup: true - name: Run checkstyle using gradle run: ./gradlew checkstyleMain checkstyleTest checkstyleJmh - - name: Add comment on pull request - if: ${{ failure() }} - uses: thollander/actions-comment-pull-request@v2 - with: - message: > - Your code currently does not meet [JabRef's code guidelines](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html). - We use [Checkstyle](https://checkstyle.sourceforge.io/) to identify issues. - The tool reviewdog already placed comments on GitHub to indicate the places. See the tab "Files" in you PR. - Please carefully follow [the setup guide for the codestyle](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html). - Afterwards, please [run checkstyle locally](https://devdocs.jabref.org/getting-into-the-code/guidelines-for-setting-up-a-local-workspace/intellij-13-code-style.html#run-checkstyle) and fix the issues. - You can check review dog's comments at the tab "Files changed" of your pull request. - comment_tag: automated-test-feedback - openrewrite: name: OpenRewrite runs-on: ubuntu-latest @@ -88,19 +74,6 @@ jobs: - name: Run OpenRewrite run: | ./gradlew rewriteDryRun - - name: Add comment on pull request - if: ${{ failure() }} - uses: thollander/actions-comment-pull-request@v2 - with: - message: > - Your code currently does not meet JabRef's code guidelines. - We use [OpenRewrite](https://docs.openrewrite.org/) to ensure "modern" Java coding practices. - The issues found can be **automatically fixed**. - Please execute the gradle task *`rewriteRun`*, check the results, commit, and push. - - - You can check the detailed error output by navigating to your pull request, selecting the tab "Checks", section "Tests" (on the left), subsection "OpenRewrite". - comment_tag: automated-test-feedback modernizer: name: Modernizer @@ -125,18 +98,6 @@ jobs: # enable failing of this task if modernizer complains sed -i "s/failOnViolations = false/failOnViolations = true/" build.gradle ./gradlew modernizer - - name: Add comment on pull request - if: ${{ failure() }} - uses: thollander/actions-comment-pull-request@v2 - with: - message: > - Your code currently does not meet JabRef's code guidelines. - We use [Gradle Modernizer Plugin](https://github.com/andygoossens/gradle-modernizer-plugin#gradle-modernizer-plugin) to ensure "modern" Java coding practices. - Please fix the detected errors, commit, and push. - - - You can check the detailed error output by navigating to your pull request, selecting the tab "Checks", section "Tests" (on the left), subsection "Modernizer". - comment_tag: automated-test-feedback markdown: name: Markdown @@ -153,18 +114,6 @@ jobs: globs: | *.md docs/**/*.md - - name: Add comment on pull request - if: ${{ failure() }} - uses: thollander/actions-comment-pull-request@v2 - with: - message: > - You modified Markdown (`*.md`) files and did not meet JabRef's rules for consistently formatted Markdown files. - To ensure consistent styling, we have [markdown-lint](https://github.com/DavidAnson/markdownlint) in place. - [Markdown lint's rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#rules) help to keep our Markdown files consistent within this repository and consistent with the Markdown files outside here. - - - You can check the detailed error output by navigating to your pull request, selecting the tab "Checks", section "Tests" (on the left), subsection "Markdown". - comment_tag: automated-test-feedback changelog: name: CHANGELOG.md @@ -213,14 +162,6 @@ jobs: diff \ <(git show origin/main:CHANGELOG.md | clparse --format=json --separator=– - | jq '.releases[] | select(.version != null)') \ <(git show HEAD:CHANGELOG.md | clparse --format=json --separator=– - | jq '.releases[] | select(.version != null)') - - name: Add comment on pull request - if: ${{ failure() }} - uses: thollander/actions-comment-pull-request@v2 - with: - message: > - While the PR was in progress, JabRef released a new version. - You have to merge `upstream/main` and move your entry in `CHANGELOG.md` up to the section `## [Unreleased]`. - comment_tag: automated-test-feedback tests: name: Unit tests From 72e39b7704b1610b37c009b7c4ed0adcdc500832 Mon Sep 17 00:00:00 2001 From: subhramit Date: Tue, 13 Aug 2024 01:46:55 +0530 Subject: [PATCH 93/94] Fix checkstyle --- src/main/java/org/jabref/gui/openoffice/OOBibBase.java | 1 - .../jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java index 2f9f4fc4bfb..f24b98d8712 100644 --- a/src/main/java/org/jabref/gui/openoffice/OOBibBase.java +++ b/src/main/java/org/jabref/gui/openoffice/OOBibBase.java @@ -944,7 +944,6 @@ public void guiActionUpdateDocument(List databases, OOStyle style) BibDatabaseContext bibDatabaseContext = new BibDatabaseContext(bibDatabase); cslUpdateBibliography.rebuildCSLBibliography(doc, cslCitationOOAdapter, citedEntries, citationStyle, bibDatabaseContext, Injector.instantiateModelOrService(BibEntryTypesManager.class)); - } catch (NoDocumentException | NoSuchElementException e) { throw new RuntimeException(e); diff --git a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java index 08dee193f91..ecb0fa932e5 100644 --- a/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java +++ b/src/main/java/org/jabref/logic/openoffice/oocsltext/CSLCitationOOAdapter.java @@ -66,7 +66,6 @@ public void insertBibliography(XTextCursor cursor, CitationStyle selectedStyle, String citation = CitationStyleGenerator.generateCitation(List.of(entry), style, format, bibDatabaseContext, bibEntryTypesManager).getFirst(); String citationKey = entry.getCitationKey().orElse(""); int currentNumber = markManager.getCitationNumber(citationKey); - System.out.println(citation); String formattedCitation; if (selectedStyle.isNumericStyle()) { From cdd0799f96df4d43b924e2bbb1b64bee6a2dc6a5 Mon Sep 17 00:00:00 2001 From: Ruslan Date: Mon, 12 Aug 2024 23:28:50 +0300 Subject: [PATCH 94/94] Add more organizations related to AI features to PRIVACY.md (#11611) * Add more organization related to AI features to PRIVACY.md * Add expanded form of DJL --- PRIVACY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PRIVACY.md b/PRIVACY.md index e1ba61f9a95..853f5371530 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -49,18 +49,21 @@ These third-party services are the following: | [Collection of Computer Science Bibliographies](https://en.wikipedia.org/wiki/Collection_of_Computer_Science_Bibliographies) | **currently unavailable**, offline | | [CrossRef](https://www.crossref.org/) | | | [dblp](https://dblp.uni-trier.de/) | | +| [DJL (Deep Java Library)](https://djl.ai/) | | | [Directory of Open Access Books](https://www.doabooks.org/) | | | [Digitala Vetenskapliga Arkivet](https://www.diva-portal.org/) | | | [DOI Foundation](https://www.doi.org/) | | | [Elsevier](https://www.elsevier.com/) | | | [Google Scholar](https://scholar.google.com/) | | | [Gemeinsamer Verbundkatalog](https://www.gbv.de/) | | +| [Hugging Face](https://huggingface.co/) | | | [IACR](https://www.iacr.org/) | | | [IEEEXplore](https://ieeexplore.ieee.org/Xplore/home.jsp) | | | [INSPIRE](https://inspirehep.net/) | | | [ISIDORE](https://isidore.science/) | | | [JSTOR](https://www.jstor.org/) | | | [Library of Congress](https://lccn.loc.gov/) | | +| [Mistral AI](https://mistral.ai/) | | | [National Library of Medicine](https://www.ncbi.nlm.nih.gov/) | | | [MathSciNet](http://www.ams.org/mathscinet) | | | [mEDRA](https://www.medra.org/) | |