From e43d795c0cd41fc281923e304de53b5824dcf758 Mon Sep 17 00:00:00 2001 From: tushar Date: Sat, 16 Aug 2025 19:08:52 +0530 Subject: [PATCH 1/2] Added CiteFormatter and BibLatexFormatter for CAYW feature --- jabref | 1 + .../server/cayw/format/BibLatexFormatter.java | 8 ++-- .../server/cayw/format/CAYWFormatter.java | 2 +- .../server/cayw/format/CiteFormatter.java | 42 +++++++++++++++++++ .../server/cayw/format/FormatterService.java | 7 ++++ .../server/cayw/format/LatexFormatter.java | 42 +++++++++++++++++++ .../http/server/cayw/format/MMDFormatter.java | 36 ++++++++++++++++ .../server/cayw/format/PandocFormatter.java | 36 ++++++++++++++++ .../cayw/format/SimpleJsonFormatter.java | 8 ++-- .../server/cayw/format/TypstFormatter.java | 36 ++++++++++++++++ .../server/cayw/format/nabbingFormatter.java | 42 +++++++++++++++++++ 11 files changed, 251 insertions(+), 9 deletions(-) create mode 160000 jabref create mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/CiteFormatter.java create mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java create mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/MMDFormatter.java create mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java create mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java create mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java diff --git a/jabref b/jabref new file mode 160000 index 00000000000..bbb88ccd377 --- /dev/null +++ b/jabref @@ -0,0 +1 @@ +Subproject commit bbb88ccd377c754e70c6d92a818db00d43bd6d09 diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java index 573a7e36c2f..8b329fca800 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java @@ -24,12 +24,12 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List caywEntries) { + public String format(CAYWQueryParams queryParams, List cawEntries) { String command = queryParams.getCommand(); - List bibEntries = caywEntries.stream() - .map(CAYWEntry::bibEntry) - .toList(); + List bibEntries = cawEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); return "\\%s{%s}".formatted(command, bibEntries.stream() diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java index ed7d652a383..fc6e9dbd3b1 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java @@ -13,5 +13,5 @@ public interface CAYWFormatter { MediaType getMediaType(); - String format(CAYWQueryParams caywQueryParams, List caywEntries); + String format(CAYWQueryParams caywQueryParams, List cawEntries); } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CiteFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CiteFormatter.java new file mode 100644 index 00000000000..aa47ada50a5 --- /dev/null +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CiteFormatter.java @@ -0,0 +1,42 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.core.MediaType; +import org.jvnet.hk2.annotations.Service; + +@Service +public class CiteFormatter implements CAYWFormatter { + + @Override + public String getFormatName() { + return "citep"; + } + + @Override + public MediaType getMediaType() { + return MediaType.TEXT_PLAIN_TYPE; + } + + @Override + public String format(CAYWQueryParams queryParams, List cawEntries) { + String command = queryParams.getCommand(); + if (command == null || command.isBlank()) { + command = "citep"; // default for citep + } + + List bibEntries = cawEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + + return "\\%s{%s}".formatted(command, + bibEntries.stream() + .map(entry -> entry.getCitationKey().orElse("")) + .collect(Collectors.joining(","))); + } +} diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java index 4cb608d6196..07b8ce3324c 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java @@ -17,6 +17,13 @@ public FormatterService() { this.formatters = new HashMap<>(); registerFormatter(new SimpleJsonFormatter()); registerFormatter(new BibLatexFormatter()); + registerFormatter(new LatexFormatter()); + registerFormatter(new CiteFormatter()); + registerFormatter(new nabbingFormatter()); + registerFormatter(new MMDFormatter()); + registerFormatter(new PandocFormatter()); + registerFormatter(new TypstFormatter()); + registerFormatter(new SimpleJsonFormatter()); } public void registerFormatter(CAYWFormatter formatter) { diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java new file mode 100644 index 00000000000..6c7b235a4da --- /dev/null +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java @@ -0,0 +1,42 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.core.MediaType; +import org.jvnet.hk2.annotations.Service; + +@Service +public class LatexFormatter implements CAYWFormatter { + + @Override + public String getFormatName() { + return "latex"; + } + + @Override + public MediaType getMediaType() { + return MediaType.TEXT_PLAIN_TYPE; + } + + @Override + public String format(CAYWQueryParams queryParams, List cawEntries) { + String command = Optional.ofNullable(queryParams.getCommand()) + .filter(cmd -> !cmd.isBlank()) + .orElse("cite"); + + List bibEntries = cawEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + + return "\\%s{%s}".formatted(command, + bibEntries.stream() + .map(entry -> entry.getCitationKey().orElse("")) + .collect(Collectors.joining(","))); + } +} diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/MMDFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/MMDFormatter.java new file mode 100644 index 00000000000..4f79fe37bed --- /dev/null +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/MMDFormatter.java @@ -0,0 +1,36 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.core.MediaType; +import org.jvnet.hk2.annotations.Service; + +@Service +public class MMDFormatter implements CAYWFormatter { + + @Override + public String getFormatName() { + return "mmd"; + } + + @Override + public MediaType getMediaType() { + return MediaType.TEXT_PLAIN_TYPE; + } + + @Override + public String format(CAYWQueryParams queryParams, List cawEntries) { + List bibEntries = cawEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + + return bibEntries.stream() + .map(entry -> "[@"+ entry.getCitationKey().orElse("") + "]") + .collect(Collectors.joining(" ")); + } +} diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java new file mode 100644 index 00000000000..ae7a5047d3d --- /dev/null +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java @@ -0,0 +1,36 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.core.MediaType; +import org.jvnet.hk2.annotations.Service; + +@Service +public class PandocFormatter implements CAYWFormatter { + + @Override + public String getFormatName() { + return "pandoc"; + } + + @Override + public MediaType getMediaType() { + return MediaType.TEXT_PLAIN_TYPE; + } + + @Override + public String format(CAYWQueryParams queryParams, List cawEntries) { + List bibEntries = cawEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + + return bibEntries.stream() + .map(entry -> "[@"+ entry.getCitationKey().orElse("") + "]") + .collect(Collectors.joining(" ")); + } +} diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java index 480df4becfa..98f2e8baac3 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java @@ -31,10 +31,10 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List caywEntries) { - List simpleJsons = caywEntries.stream() - .map(caywEntry -> SimpleJson.fromBibEntry(caywEntry.bibEntry())) - .toList(); + public String format(CAYWQueryParams queryParams, List cawEntries) { + List simpleJsons = cawEntries.stream() + .map(caywEntry -> SimpleJson.fromBibEntry(caywEntry.bibEntry())) + .toList(); return gson.toJson(simpleJsons); } } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java new file mode 100644 index 00000000000..c39dd0819a6 --- /dev/null +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java @@ -0,0 +1,36 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.core.MediaType; +import org.jvnet.hk2.annotations.Service; + +@Service +public class TypstFormatter implements CAYWFormatter { + + @Override + public String getFormatName() { + return "typst"; + } + + @Override + public MediaType getMediaType() { + return MediaType.TEXT_PLAIN_TYPE; + } + + @Override + public String format(CAYWQueryParams queryParams, List cawEntries) { + List bibEntries = cawEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + + return bibEntries.stream() + .map(entry -> "@" + entry.getCitationKey().orElse("")) + .collect(Collectors.joining(" ")); + } +} diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java new file mode 100644 index 00000000000..d17631f7039 --- /dev/null +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java @@ -0,0 +1,42 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.core.MediaType; +import org.jvnet.hk2.annotations.Service; + +@Service +public class nabbingFormatter implements CAYWFormatter { + + @Override + public String getFormatName() { + return "nabbing"; + } + + @Override + public MediaType getMediaType() { + return MediaType.TEXT_PLAIN_TYPE; + } + + @Override + public String format(CAYWQueryParams queryParams, List cawEntries) { + String command = queryParams.getCommand(); + if (command == null || command.isBlank()) { + command = "citep"; // default for natbib + } + + List bibEntries = cawEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + + return "\\%s{%s}".formatted(command, + bibEntries.stream() + .map(entry -> entry.getCitationKey().orElse("")) + .collect(Collectors.joining(","))); + } +} From 26177cfd2dd58265b9e86264911e82fd0f931026 Mon Sep 17 00:00:00 2001 From: tushar Date: Tue, 19 Aug 2025 20:23:46 +0530 Subject: [PATCH 2/2] additional CAYW Formatters --- .../server/cayw/format/BibLatexFormatter.java | 16 +++--- .../server/cayw/format/CAYWFormatter.java | 8 ++- .../server/cayw/format/CitepFormatter.java | 36 ++++++++++++ .../server/cayw/format/FormatterService.java | 18 +++--- .../server/cayw/format/LatexFormatter.java | 15 ++--- .../{MMDFormatter.java => MmdFormatter.java} | 19 +++---- ...iteFormatter.java => NatbibFormatter.java} | 29 +++++++--- .../server/cayw/format/PandocFormatter.java | 29 ++++++---- .../cayw/format/SimpleJsonFormatter.java | 13 ++--- .../server/cayw/format/TypstFormatter.java | 17 +++--- .../server/cayw/format/nabbingFormatter.java | 42 -------------- .../cayw/format/CitepFormatterTest.java | 46 +++++++++++++++ .../cayw/format/LatexFormatterTest.java | 20 +++++++ .../server/cayw/format/MmdFormatterTest.java | 23 ++++++++ .../cayw/format/NatbibFormatterTest.java | 14 +++++ .../cayw/format/PandocFormatterTest.java | 57 +++++++++++++++++++ .../cayw/format/TypstFormatterTest.java | 13 +++++ 17 files changed, 300 insertions(+), 115 deletions(-) create mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/CitepFormatter.java rename jabsrv/src/main/java/org/jabref/http/server/cayw/format/{MMDFormatter.java => MmdFormatter.java} (53%) rename jabsrv/src/main/java/org/jabref/http/server/cayw/format/{CiteFormatter.java => NatbibFormatter.java} (53%) delete mode 100644 jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java create mode 100644 jabsrv/src/test/java/org/jabref/http/server/cayw/format/CitepFormatterTest.java create mode 100644 jabsrv/src/test/java/org/jabref/http/server/cayw/format/LatexFormatterTest.java create mode 100644 jabsrv/src/test/java/org/jabref/http/server/cayw/format/MmdFormatterTest.java create mode 100644 jabsrv/src/test/java/org/jabref/http/server/cayw/format/NatbibFormatterTest.java create mode 100644 jabsrv/src/test/java/org/jabref/http/server/cayw/format/PandocFormatterTest.java create mode 100644 jabsrv/src/test/java/org/jabref/http/server/cayw/format/TypstFormatterTest.java diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java index 8b329fca800..85660a66f7b 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/BibLatexFormatter.java @@ -1,3 +1,5 @@ + + package org.jabref.http.server.cayw.format; import java.util.List; @@ -14,8 +16,8 @@ public class BibLatexFormatter implements CAYWFormatter { @Override - public String getFormatName() { - return "biblatex"; + public List getFormatNames() { + return List.of("biblatex"); } @Override @@ -24,13 +26,11 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { + public String format(CAYWQueryParams queryParams, List caywEntries) { String command = queryParams.getCommand(); - - List bibEntries = cawEntries.stream() - .map(CAYWEntry::bibEntry) - .toList(); - + List bibEntries = caywEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); return "\\%s{%s}".formatted(command, bibEntries.stream() .map(entry -> entry.getCitationKey().orElse("")) diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java index fc6e9dbd3b1..212d94dbf8c 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CAYWFormatter.java @@ -9,9 +9,13 @@ public interface CAYWFormatter { - String getFormatName(); + List getFormatNames(); + + default String getFormatName() { + return getFormatNames().get(0); + } MediaType getMediaType(); - String format(CAYWQueryParams caywQueryParams, List cawEntries); + String format(CAYWQueryParams caywQueryParams, List caywEntries); } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CitepFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CitepFormatter.java new file mode 100644 index 00000000000..f01b10619b4 --- /dev/null +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CitepFormatter.java @@ -0,0 +1,36 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.core.MediaType; +import org.jvnet.hk2.annotations.Service; + +@Service +public class CitepFormatter implements CAYWFormatter { + + @Override + public List getFormatNames() { + return List.of("citep", "cite"); + } + + @Override + public MediaType getMediaType() { + return MediaType.TEXT_PLAIN_TYPE; + } + + @Override + public String format(CAYWQueryParams queryParams, List caywEntries) { + List bibEntries = caywEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + String joined = bibEntries.stream() + .map(entry -> entry.getCitationKey().orElse("")) + .collect(Collectors.joining(",")); + return "\\citep{" + joined + "}"; + } +} diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java index 07b8ce3324c..de7c6545189 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/FormatterService.java @@ -9,7 +9,6 @@ @Service public class FormatterService { - private static final String DEFAULT_FORMATTER = "biblatex"; private final Map formatters; @@ -17,20 +16,25 @@ public FormatterService() { this.formatters = new HashMap<>(); registerFormatter(new SimpleJsonFormatter()); registerFormatter(new BibLatexFormatter()); + registerFormatter(new NatbibFormatter()); registerFormatter(new LatexFormatter()); - registerFormatter(new CiteFormatter()); - registerFormatter(new nabbingFormatter()); - registerFormatter(new MMDFormatter()); + registerFormatter(new CitepFormatter()); + registerFormatter(new MmdFormatter()); registerFormatter(new PandocFormatter()); registerFormatter(new TypstFormatter()); - registerFormatter(new SimpleJsonFormatter()); } public void registerFormatter(CAYWFormatter formatter) { - formatters.putIfAbsent(formatter.getFormatName(), formatter); + for (String name : formatter.getFormatNames()) { + formatters.putIfAbsent(name.toLowerCase(), formatter); + } } public CAYWFormatter getFormatter(CAYWQueryParams queryParams) { - return formatters.getOrDefault(queryParams.getFormat().toLowerCase(), formatters.get(DEFAULT_FORMATTER)); + String format = queryParams.getFormat(); + if (format == null) { + return formatters.get(DEFAULT_FORMATTER); + } + return formatters.getOrDefault(format.toLowerCase(), formatters.get(DEFAULT_FORMATTER)); } } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java index 6c7b235a4da..56d0a17bbd4 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/LatexFormatter.java @@ -1,7 +1,6 @@ package org.jabref.http.server.cayw.format; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; import org.jabref.http.server.cayw.CAYWQueryParams; @@ -15,8 +14,8 @@ public class LatexFormatter implements CAYWFormatter { @Override - public String getFormatName() { - return "latex"; + public List getFormatNames() { + return List.of("latex", "tex"); } @Override @@ -25,15 +24,11 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { - String command = Optional.ofNullable(queryParams.getCommand()) - .filter(cmd -> !cmd.isBlank()) - .orElse("cite"); - - List bibEntries = cawEntries.stream() + public String format(CAYWQueryParams queryParams, List caywEntries) { + String command = queryParams.getCommand() != null ? queryParams.getCommand() : "autocite"; + List bibEntries = caywEntries.stream() .map(CAYWEntry::bibEntry) .toList(); - return "\\%s{%s}".formatted(command, bibEntries.stream() .map(entry -> entry.getCitationKey().orElse("")) diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/MMDFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/MmdFormatter.java similarity index 53% rename from jabsrv/src/main/java/org/jabref/http/server/cayw/format/MMDFormatter.java rename to jabsrv/src/main/java/org/jabref/http/server/cayw/format/MmdFormatter.java index 4f79fe37bed..867c040befc 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/MMDFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/MmdFormatter.java @@ -11,11 +11,11 @@ import org.jvnet.hk2.annotations.Service; @Service -public class MMDFormatter implements CAYWFormatter { +public class MmdFormatter implements CAYWFormatter { @Override - public String getFormatName() { - return "mmd"; + public List getFormatNames() { + return List.of("mmd", "multimarkdown"); } @Override @@ -24,13 +24,12 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { - List bibEntries = cawEntries.stream() - .map(CAYWEntry::bibEntry) - .toList(); - + public String format(CAYWQueryParams queryParams, List caywEntries) { + List bibEntries = caywEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); return bibEntries.stream() - .map(entry -> "[@"+ entry.getCitationKey().orElse("") + "]") - .collect(Collectors.joining(" ")); + .map(bibEntry -> "[@" + bibEntry.getCitationKey().orElse("") + "]") + .collect(Collectors.joining("")); } } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CiteFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/NatbibFormatter.java similarity index 53% rename from jabsrv/src/main/java/org/jabref/http/server/cayw/format/CiteFormatter.java rename to jabsrv/src/main/java/org/jabref/http/server/cayw/format/NatbibFormatter.java index aa47ada50a5..932f459279c 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/CiteFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/NatbibFormatter.java @@ -11,11 +11,11 @@ import org.jvnet.hk2.annotations.Service; @Service -public class CiteFormatter implements CAYWFormatter { +public class NatbibFormatter implements CAYWFormatter { @Override - public String getFormatName() { - return "citep"; + public List getFormatNames() { + return List.of("natbib", "nat"); } @Override @@ -24,19 +24,30 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { + public String format(CAYWQueryParams queryParams, List caywEntries) { String command = queryParams.getCommand(); - if (command == null || command.isBlank()) { - command = "citep"; // default for citep + if (command == null) { + command = "citep"; } - List bibEntries = cawEntries.stream() - .map(CAYWEntry::bibEntry) - .toList(); + command = mapToNatbibCommand(command); + + List bibEntries = caywEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); return "\\%s{%s}".formatted(command, bibEntries.stream() .map(entry -> entry.getCitationKey().orElse("")) .collect(Collectors.joining(","))); } + + private String mapToNatbibCommand(String command) { + return switch (command) { + case "author" -> "citeauthor"; + case "textcite" -> "citet"; + case "year" -> "citeyear"; + default -> command; + }; + } } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java index ae7a5047d3d..cf6d507b88f 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/PandocFormatter.java @@ -12,10 +12,9 @@ @Service public class PandocFormatter implements CAYWFormatter { - @Override - public String getFormatName() { - return "pandoc"; + public List getFormatNames() { + return List.of("pandoc", "markdown"); } @Override @@ -24,13 +23,21 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { - List bibEntries = cawEntries.stream() - .map(CAYWEntry::bibEntry) - .toList(); - - return bibEntries.stream() - .map(entry -> "[@"+ entry.getCitationKey().orElse("") + "]") - .collect(Collectors.joining(" ")); + public String format(CAYWQueryParams queryParams, List caywEntries) { + String command = queryParams.getCommand(); + List bibEntries = caywEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); + // Handle "parencite" command with square brackets + if ("parencite".equalsIgnoreCase(command)) { + return bibEntries.stream() + .map(bibEntry -> "[@" + bibEntry.getCitationKey().orElse("") + "]") + .collect(Collectors.joining("")); + } else { + // Default: bare @key format with semicolon separator + return bibEntries.stream() + .map(bibEntry -> "@" + bibEntry.getCitationKey().orElse("")) + .collect(Collectors.joining("; ")); + } } } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java index 98f2e8baac3..a74247aebb6 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/SimpleJsonFormatter.java @@ -13,7 +13,6 @@ @Service public class SimpleJsonFormatter implements CAYWFormatter { - private final Gson gson; public SimpleJsonFormatter() { @@ -21,8 +20,8 @@ public SimpleJsonFormatter() { } @Override - public String getFormatName() { - return "simple-json"; + public List getFormatNames() { + return List.of("simple-json"); } @Override @@ -31,10 +30,10 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { - List simpleJsons = cawEntries.stream() - .map(caywEntry -> SimpleJson.fromBibEntry(caywEntry.bibEntry())) - .toList(); + public String format(CAYWQueryParams queryParams, List caywEntries) { + List simpleJsons = caywEntries.stream() + .map(caywEntry -> SimpleJson.fromBibEntry(caywEntry.bibEntry())) + .toList(); return gson.toJson(simpleJsons); } } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java index c39dd0819a6..feb11afc28c 100644 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java +++ b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/TypstFormatter.java @@ -14,8 +14,8 @@ public class TypstFormatter implements CAYWFormatter { @Override - public String getFormatName() { - return "typst"; + public List getFormatNames() { + return List.of("typst", "typ"); } @Override @@ -24,13 +24,12 @@ public MediaType getMediaType() { } @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { - List bibEntries = cawEntries.stream() - .map(CAYWEntry::bibEntry) - .toList(); - + public String format(CAYWQueryParams queryParams, List caywEntries) { + List bibEntries = caywEntries.stream() + .map(CAYWEntry::bibEntry) + .toList(); return bibEntries.stream() - .map(entry -> "@" + entry.getCitationKey().orElse("")) - .collect(Collectors.joining(" ")); + .map(bibEntry -> "@" + bibEntry.getCitationKey().orElse("")) + .collect(Collectors.joining(", ")); } } diff --git a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java b/jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java deleted file mode 100644 index d17631f7039..00000000000 --- a/jabsrv/src/main/java/org/jabref/http/server/cayw/format/nabbingFormatter.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.jabref.http.server.cayw.format; - -import java.util.List; -import java.util.stream.Collectors; - -import org.jabref.http.server.cayw.CAYWQueryParams; -import org.jabref.http.server.cayw.gui.CAYWEntry; -import org.jabref.model.entry.BibEntry; - -import jakarta.ws.rs.core.MediaType; -import org.jvnet.hk2.annotations.Service; - -@Service -public class nabbingFormatter implements CAYWFormatter { - - @Override - public String getFormatName() { - return "nabbing"; - } - - @Override - public MediaType getMediaType() { - return MediaType.TEXT_PLAIN_TYPE; - } - - @Override - public String format(CAYWQueryParams queryParams, List cawEntries) { - String command = queryParams.getCommand(); - if (command == null || command.isBlank()) { - command = "citep"; // default for natbib - } - - List bibEntries = cawEntries.stream() - .map(CAYWEntry::bibEntry) - .toList(); - - return "\\%s{%s}".formatted(command, - bibEntries.stream() - .map(entry -> entry.getCitationKey().orElse("")) - .collect(Collectors.joining(","))); - } -} diff --git a/jabsrv/src/test/java/org/jabref/http/server/cayw/format/CitepFormatterTest.java b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/CitepFormatterTest.java new file mode 100644 index 00000000000..f2cf76de613 --- /dev/null +++ b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/CitepFormatterTest.java @@ -0,0 +1,46 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.Optional; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +final class CitepFormatterTest { + + private CAYWEntry stubEntry(String key) { + BibEntry bib = mock(BibEntry.class); + when(bib.getCitationKey()).thenReturn(Optional.of(key)); + + CAYWEntry cayw = mock(CAYWEntry.class); + when(cayw.bibEntry()).thenReturn(bib); + return cayw; + } + + @Test + @DisplayName("getFormatNames() returns the two expected aliases in order") + void testGetFormatNames() { + CitepFormatter f = new CitepFormatter(); + assertEquals(List.of("citep", "cite"), f.getFormatNames()); + } + + @Test + @DisplayName("format() produces \\citep{key1,key2}") + void testFormat() { + CitepFormatter f = new CitepFormatter(); + + CAYWQueryParams qp = mock(CAYWQueryParams.class); // command is ignored + List entries = List.of(stubEntry("key1"), stubEntry("key2")); + + String out = f.format(qp, entries); + assertEquals("\\citep{key1,key2}", out); + } +} diff --git a/jabsrv/src/test/java/org/jabref/http/server/cayw/format/LatexFormatterTest.java b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/LatexFormatterTest.java new file mode 100644 index 00000000000..1f0eb77f53e --- /dev/null +++ b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/LatexFormatterTest.java @@ -0,0 +1,20 @@ +package org.jabref.http.server.cayw.format; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +final class LatexFormatterTest { + + @Test + void testGetFormatNamesNotEmpty() { + LatexFormatter f = new LatexFormatter(); + assertFalse(f.getFormatNames().isEmpty(), "Format-name list must not be empty"); + } + + @Test + void testMediaTypeIsTextPlain() { + assertEquals("text/plain", new LatexFormatter().getMediaType().toString()); + } +} diff --git a/jabsrv/src/test/java/org/jabref/http/server/cayw/format/MmdFormatterTest.java b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/MmdFormatterTest.java new file mode 100644 index 00000000000..c7bbfbaa107 --- /dev/null +++ b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/MmdFormatterTest.java @@ -0,0 +1,23 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +final class MmdFormatterTest { + + @Test + void testGetFormatNamesNotEmpty() { + assertFalse(new MmdFormatter().getFormatNames().isEmpty()); + } + + @Test + void testAliasesUnique() { + List names = new MmdFormatter().getFormatNames(); + assertEquals(names.size(), names.stream().distinct().count(), + "Aliases must be unique"); + } +} diff --git a/jabsrv/src/test/java/org/jabref/http/server/cayw/format/NatbibFormatterTest.java b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/NatbibFormatterTest.java new file mode 100644 index 00000000000..651253cfb0c --- /dev/null +++ b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/NatbibFormatterTest.java @@ -0,0 +1,14 @@ +package org.jabref.http.server.cayw.format; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +final class NatbibFormatterTest { + + @Test + void testHasAtLeastTwoAliases() { + assertTrue(new NatbibFormatter().getFormatNames().size() >= 2, + "Natbib formatter should expose ≥ 3 aliases"); + } +} diff --git a/jabsrv/src/test/java/org/jabref/http/server/cayw/format/PandocFormatterTest.java b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/PandocFormatterTest.java new file mode 100644 index 00000000000..4f07b11745c --- /dev/null +++ b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/PandocFormatterTest.java @@ -0,0 +1,57 @@ +package org.jabref.http.server.cayw.format; + +import java.util.List; +import java.util.Optional; + +import org.jabref.http.server.cayw.CAYWQueryParams; +import org.jabref.http.server.cayw.gui.CAYWEntry; +import org.jabref.model.entry.BibEntry; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +final class PandocFormatterTest { + + private CAYWEntry stubEntry(String key) { + BibEntry bib = mock(BibEntry.class); + when(bib.getCitationKey()).thenReturn(Optional.of(key)); + + CAYWEntry cayw = mock(CAYWEntry.class); + when(cayw.bibEntry()).thenReturn(bib); + return cayw; + } + + @Test + void testGetFormatNames() { + PandocFormatter f = new PandocFormatter(); + assertEquals(List.of("pandoc", "markdown"), f.getFormatNames()); + } + + @Test + @DisplayName("Default command ⇒ '@k1; @k2'") + void testDefaultFormat() { + PandocFormatter f = new PandocFormatter(); + + CAYWQueryParams qp = mock(CAYWQueryParams.class); + when(qp.getCommand()).thenReturn(null); + + String out = f.format(qp, List.of(stubEntry("k1"), stubEntry("k2"))); + assertEquals("@k1; @k2", out); + } + + @Test + @DisplayName("parencite command ⇒ '[@k1][@k2]…'") + void testParenciteFormat() { + PandocFormatter f = new PandocFormatter(); + + CAYWQueryParams qp = mock(CAYWQueryParams.class); + when(qp.getCommand()).thenReturn("parencite"); + + String out = f.format(qp, List.of(stubEntry("k1"), stubEntry("k2"))); + assertEquals("[@k1][@k2]", out); + } +} diff --git a/jabsrv/src/test/java/org/jabref/http/server/cayw/format/TypstFormatterTest.java b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/TypstFormatterTest.java new file mode 100644 index 00000000000..acbc39100b1 --- /dev/null +++ b/jabsrv/src/test/java/org/jabref/http/server/cayw/format/TypstFormatterTest.java @@ -0,0 +1,13 @@ +package org.jabref.http.server.cayw.format; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +final class TypstFormatterTest { + + @Test + void testFirstAliasIsTypst() { + assertEquals("typst", new TypstFormatter().getFormatNames().get(0)); + } +}