Skip to content

Commit b453985

Browse files
LinusDietzcalixtussubhramitSiedlerchr
authored
Markdown Export Formatter (#12220)
* Add Markdown export formatter * updated the changelog * fix checkstyle and l10n * fix import order * Update CHANGELOG.md Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> * Add full stop (changelog) * remove explicit save order - just for test * checkstyle * temp dir --------- Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com> Co-authored-by: Subhramit Basu Bhowmick <subhramit.bb@live.in> Co-authored-by: Siedlerchr <siedlerkiller@gmail.com>
1 parent dc9c49f commit b453985

File tree

9 files changed

+201
-0
lines changed

9 files changed

+201
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
1111

1212
### Added
1313

14+
- We added a Markdown export layout. [#12220](https://github.com/JabRef/jabref/pull/12220)
1415
- We added a "view as BibTeX" option before importing an entry from the citation relation tab. [#11826](https://github.com/JabRef/jabref/issues/11826)
1516
- We added support finding LaTeX-encoded special characters based on plain Unicode and vice versa. [#11542](https://github.com/JabRef/jabref/pull/11542)
1617
- When a search hits a file, the file icon of that entry is changed accordingly. [#11542](https://github.com/JabRef/jabref/pull/11542)

src/main/java/org/jabref/logic/exporter/ExporterFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public static ExporterFactory create(CliPreferences preferences) {
4343
exporters.add(new TemplateExporter(Localization.lang("HTML table"), "tablerefs", "tablerefs", "tablerefs", StandardFileType.HTML, layoutPreferences, saveOrder));
4444
exporters.add(new TemplateExporter(Localization.lang("HTML list"), "listrefs", "listrefs", "listrefs", StandardFileType.HTML, layoutPreferences, saveOrder));
4545
exporters.add(new TemplateExporter(Localization.lang("HTML table (with Abstract & BibTeX)"), "tablerefsabsbib", "tablerefsabsbib", "tablerefsabsbib", StandardFileType.HTML, layoutPreferences, saveOrder));
46+
exporters.add(new TemplateExporter(Localization.lang("Markdown titles"), "title-md", "title-md", "title-markdown", StandardFileType.MARKDOWN, layoutPreferences, saveOrder));
4647
exporters.add(new TemplateExporter("Harvard RTF", "harvard", "harvard", "harvard", StandardFileType.RTF, layoutPreferences, saveOrder));
4748
exporters.add(new TemplateExporter("ISO 690 RTF", "iso690rtf", "iso690RTF", "iso690rtf", StandardFileType.RTF, layoutPreferences, saveOrder));
4849
exporters.add(new TemplateExporter("ISO 690", "iso690txt", "iso690", "iso690txt", StandardFileType.TXT, layoutPreferences, saveOrder));

src/main/resources/l10n/JabRef_en.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,8 @@ The\ marked\ area\ does\ not\ contain\ any\ legible\ text!=The marked area does
466466

467467
HTML\ table=HTML table
468468
HTML\ table\ (with\ Abstract\ &\ BibTeX)=HTML table (with Abstract & BibTeX)
469+
Markdown\ titles=Markdown titles
470+
469471
Icon=Icon
470472

471473
Ignore=Ignore
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* \format[RemoveLatexCommands,HTMLChars]{\title}. \begin{journal}\format[RemoveLatexCommands,HTMLChars]{\journal}\end{journal}\begin{year} \format{\year}\end{year}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* \format[RemoveLatexCommands,HTMLChars]{\title}.\begin{publisher} \format[RemoveLatexCommands,HTMLChars]{\publisher}\end{publisher} \format{\year}\end{year}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* \format[RemoveLatexCommands,HTMLChars]{\title}. \begin{booktitle}\format[RemoveLatexCommands,HTMLChars]{\booktitle}\end{booktitle}\begin{publisher}, \format[RemoveLatexCommands,HTMLChars]{\publisher}\end{publisher} \format{\year}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* \format[RemoveLatexCommands,HTMLChars]{\title}. \begin{publisher}\format[RemoveLatexCommands,HTMLChars]{\publisher} \end{publisher}\begin{series}\format[RemoveLatexCommands,HTMLChars]{\series}\end{series}\begin{!series}\format[RemoveLatexCommands,HTMLChars]{\booktitle} \format{\year}\end{!series}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* \format[RemoveLatexCommands,HTMLChars]{\title}.\begin{year} \year\end{year}
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
package org.jabref.logic.exporter;
2+
3+
import java.nio.file.Files;
4+
import java.nio.file.Path;
5+
import java.util.Collections;
6+
import java.util.List;
7+
8+
import org.jabref.logic.layout.LayoutFormatterPreferences;
9+
import org.jabref.logic.util.StandardFileType;
10+
import org.jabref.model.database.BibDatabaseContext;
11+
import org.jabref.model.entry.BibEntry;
12+
import org.jabref.model.entry.field.StandardField;
13+
import org.jabref.model.entry.types.StandardEntryType;
14+
import org.jabref.model.metadata.SaveOrder;
15+
import org.jabref.model.metadata.SelfContainedSaveOrder;
16+
17+
import org.junit.jupiter.api.BeforeAll;
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.io.TempDir;
20+
import org.mockito.Answers;
21+
22+
import static org.junit.jupiter.api.Assertions.assertEquals;
23+
import static org.mockito.Mockito.mock;
24+
25+
class MarkdownTitleExporterTest {
26+
27+
private static Exporter htmlWebsiteExporter;
28+
private static BibDatabaseContext databaseContext;
29+
private static final SelfContainedSaveOrder SAVE_MOST_RECENT_FIRST_SAVE_ORDER = new SelfContainedSaveOrder(SaveOrder.OrderType.SPECIFIED, List.of(new SaveOrder.SortCriterion(StandardField.YEAR, true)));
30+
31+
@BeforeAll
32+
static void setUp() {
33+
htmlWebsiteExporter = new TemplateExporter(
34+
"Title-Markdown",
35+
"title-md",
36+
"title-md",
37+
"title-markdown",
38+
StandardFileType.MARKDOWN,
39+
mock(LayoutFormatterPreferences.class, Answers.RETURNS_DEEP_STUBS),
40+
SAVE_MOST_RECENT_FIRST_SAVE_ORDER,
41+
BlankLineBehaviour.DELETE_BLANKS);
42+
43+
databaseContext = new BibDatabaseContext();
44+
}
45+
46+
@Test
47+
final void exportForNoEntriesWritesNothing(@TempDir Path tempDir) throws Exception {
48+
Path file = tempDir.resolve("ThisIsARandomlyNamedFile");
49+
Files.createFile(file);
50+
htmlWebsiteExporter.export(databaseContext, tempDir, Collections.emptyList());
51+
assertEquals(Collections.emptyList(), Files.readAllLines(file));
52+
}
53+
54+
@Test
55+
final void exportsCorrectContentArticle(@TempDir Path tempDir) throws Exception {
56+
BibEntry entry = new BibEntry(StandardEntryType.Article)
57+
.withCitationKey("test")
58+
.withField(StandardField.AUTHOR, "Test Author")
59+
.withField(StandardField.TITLE, "Test Title")
60+
.withField(StandardField.JOURNAL, "Journal of this \\& that")
61+
.withField(StandardField.PUBLISHER, "THE PRESS")
62+
.withField(StandardField.YEAR, "2020");
63+
64+
Path file = tempDir.resolve("RandomFileName");
65+
Files.createFile(file);
66+
htmlWebsiteExporter.export(databaseContext, file, Collections.singletonList(entry));
67+
68+
List<String> expected = List.of(
69+
"* Test Title. Journal of this &amp; that 2020");
70+
71+
assertEquals(expected, Files.readAllLines(file));
72+
}
73+
74+
@Test
75+
final void exportsCorrectContentInCollection(@TempDir Path tempDir) throws Exception {
76+
BibEntry entry = new BibEntry(StandardEntryType.InCollection)
77+
.withCitationKey("test")
78+
.withField(StandardField.AUTHOR, "Test Author")
79+
.withField(StandardField.TITLE, "Test Title")
80+
.withField(StandardField.BOOKTITLE, "Test book")
81+
.withField(StandardField.PUBLISHER, "PRESS")
82+
.withField(StandardField.YEAR, "2020");
83+
84+
Path file = tempDir.resolve("RandomFileName");
85+
Files.createFile(file);
86+
htmlWebsiteExporter.export(databaseContext, file, Collections.singletonList(entry));
87+
88+
List<String> expected = List.of(
89+
"* Test Title. Test book, PRESS 2020");
90+
91+
assertEquals(expected, Files.readAllLines(file));
92+
}
93+
94+
@Test
95+
final void exportsCorrectContentBook(@TempDir Path tempDir) throws Exception {
96+
BibEntry entry = new BibEntry(StandardEntryType.Book)
97+
.withCitationKey("test")
98+
.withField(StandardField.AUTHOR, "Test Author")
99+
.withField(StandardField.TITLE, "Test Title")
100+
.withField(StandardField.BOOKTITLE, "Test book")
101+
.withField(StandardField.PUBLISHER, "PRESS")
102+
.withField(StandardField.YEAR, "2020");
103+
104+
Path file = tempDir.resolve("RandomFileName");
105+
Files.createFile(file);
106+
htmlWebsiteExporter.export(databaseContext, file, Collections.singletonList(entry));
107+
108+
List<String> expected = List.of(
109+
"* Test Title. PRESS 2020");
110+
111+
assertEquals(expected, Files.readAllLines(file));
112+
}
113+
114+
@Test
115+
final void exportsCorrectContentInProceeedingsPublisher(@TempDir Path tempDir) throws Exception {
116+
BibEntry entry = new BibEntry(StandardEntryType.InProceedings)
117+
.withCitationKey("test")
118+
.withField(StandardField.AUTHOR, "Test Author")
119+
.withField(StandardField.TITLE, "Test Title")
120+
.withField(StandardField.BOOKTITLE, "Test Conference")
121+
.withField(StandardField.PUBLISHER, "ACM")
122+
.withField(StandardField.SERIES, "CONF'20")
123+
.withField(StandardField.YEAR, "2020");
124+
125+
Path file = tempDir.resolve("RandomFileName");
126+
Files.createFile(file);
127+
htmlWebsiteExporter.export(databaseContext, file, Collections.singletonList(entry));
128+
129+
List<String> expected = List.of(
130+
"* Test Title. ACM CONF'20");
131+
132+
assertEquals(expected, Files.readAllLines(file));
133+
}
134+
135+
@Test
136+
final void exportsCorrectContentInProceeedingsNoPublisher(@TempDir Path tempDir) throws Exception {
137+
BibEntry entry = new BibEntry(StandardEntryType.InProceedings)
138+
.withCitationKey("test")
139+
.withField(StandardField.AUTHOR, "Test Author")
140+
.withField(StandardField.TITLE, "Test Title")
141+
.withField(StandardField.BOOKTITLE, "Test Conference")
142+
.withField(StandardField.SERIES, "CONF'20")
143+
.withField(StandardField.YEAR, "2020");
144+
145+
Path file = tempDir.resolve("RandomFileName");
146+
Files.createFile(file);
147+
htmlWebsiteExporter.export(databaseContext, file, Collections.singletonList(entry));
148+
149+
List<String> expected = List.of(
150+
"* Test Title. CONF'20");
151+
152+
assertEquals(expected, Files.readAllLines(file));
153+
}
154+
155+
@Test
156+
final void exportsCorrectContentInProceeedingsNoSeries(@TempDir Path tempDir) throws Exception {
157+
BibEntry entry = new BibEntry(StandardEntryType.InProceedings)
158+
.withCitationKey("test")
159+
.withField(StandardField.AUTHOR, "Test Author")
160+
.withField(StandardField.TITLE, "Test Title")
161+
.withField(StandardField.BOOKTITLE, "Test Conference")
162+
.withField(StandardField.YEAR, "2020");
163+
164+
Path file = tempDir.resolve("RandomFileName");
165+
Files.createFile(file);
166+
htmlWebsiteExporter.export(databaseContext, file, Collections.singletonList(entry));
167+
168+
List<String> expected = List.of(
169+
"* Test Title. Test Conference 2020");
170+
171+
assertEquals(expected, Files.readAllLines(file));
172+
}
173+
174+
@Test
175+
final void exportsCorrectContentBracketsInTitle(@TempDir Path tempDir) throws Exception {
176+
BibEntry entry = new BibEntry(StandardEntryType.Article)
177+
.withCitationKey("test")
178+
.withField(StandardField.AUTHOR, "Test Author")
179+
.withField(StandardField.TITLE, "This is {JabRef}")
180+
.withField(StandardField.JOURNAL, "Journal of this \\& that")
181+
.withField(StandardField.YEAR, "2020");
182+
183+
Path file = tempDir.resolve("RandomFileName");
184+
Files.createFile(file);
185+
htmlWebsiteExporter.export(databaseContext, file, Collections.singletonList(entry));
186+
187+
List<String> expected = List.of(
188+
"* This is JabRef. Journal of this &amp; that 2020");
189+
190+
assertEquals(expected, Files.readAllLines(file));
191+
}
192+
}

0 commit comments

Comments
 (0)