Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
48450d4
modification des fichiers qui font la configuration des exporters
sadok-lajmi Nov 5, 2025
65bbc44
Adding the empty layouts in resources/resource/layout/academicpages
GreLucie Nov 5, 2025
a4e2fea
création du fichier academicpages.article.layout
sadok-lajmi Nov 5, 2025
3e34b92
utilisation du fichier article.layout pour le new TemplateExporter
sadok-lajmi Nov 5, 2025
8e76f57
generalisation du layout en utilisant academicpages.layout
sadok-lajmi Nov 5, 2025
2799f1d
améliorations au academicpages layout
sadok-lajmi Nov 6, 2025
be96c94
ajout d'un custom formatter to help with academic layout
sadok-lajmi Nov 25, 2025
1421e98
AcademicPagesExporter
GreLucie Nov 26, 2025
e4a987c
test: add AcademicPagesExporter tests
AloisHasNeurons Nov 28, 2025
df7aa05
Delete unecessary imports
GreLucie Nov 29, 2025
9b12666
Changelog
GreLucie Nov 29, 2025
f588da4
Changed CHANGELOG.md
GreLucie Nov 29, 2025
de65527
trying to fix the CHANGELOG.md
GreLucie Nov 29, 2025
2d8afcf
Adding blankspace in CHANGELOG.md
GreLucie Nov 29, 2025
4ea372d
Correction du nouveau exporter + Cohérence des noms des fichiers prod…
sadok-lajmi Nov 29, 2025
3972b34
Merge remote-tracking branch 'origin/fix-for-issue-12727' into fix-fo…
sadok-lajmi Nov 29, 2025
9b8a86d
Reverted the date on the CHANGELOG.md and one change on AcademicPages…
GreLucie Dec 1, 2025
9087390
revert all changes to Changelog.md
GreLucie Dec 1, 2025
655afe3
format correction for the file : LayoutEntry
sadok-lajmi Dec 2, 2025
4d7dac1
Merge remote-tracking branch 'origin/fix-for-issue-12727' into fix-fo…
sadok-lajmi Dec 2, 2025
30e7626
trying to fix Open Rewrite problem
GreLucie Dec 2, 2025
6e07a52
Refactor AcademicPagesExporterTest to use full content comparison
AloisHasNeurons Dec 2, 2025
01f43cc
Merge branch 'fix-for-issue-12727' of https://github.com/GreLucie/jab…
AloisHasNeurons Dec 2, 2025
ad339be
Removed false import statement in tests.
AloisHasNeurons Dec 2, 2025
aaa5855
deleted useless import in AcademicPagesExporter.java
GreLucie Dec 2, 2025
3547cd0
Merge branch 'fix-for-issue-12727' of https://github.com/GreLucie/jab…
GreLucie Dec 2, 2025
7b55f27
correction of the error given by the localizationconsistancy test
sadok-lajmi Dec 2, 2025
ec19bb9
Merge branch 'main' into fix-for-issue-12727
sadok-lajmi Dec 4, 2025
05792cb
Merge branch 'main' into fix-for-issue-12727
GreLucie Dec 5, 2025
7ccbc6f
Updated CHANGELOG.md
GreLucie Dec 5, 2025
6f25e5c
added the link to issue 12727
GreLucie Dec 5, 2025
3c24b32
Update jablib/src/main/java/org/jabref/logic/exporter/AcademicPagesEx…
GreLucie Dec 6, 2025
b38bed2
Adressing some of the comments regarding the PR
GreLucie Dec 6, 2025
fe03fc4
Merge branch 'main' into fix-for-issue-12727
GreLucie Dec 6, 2025
c2a06e0
Comment added for replaceFormatter.setArgument(' ,-')
GreLucie Dec 6, 2025
280a1fb
tests: added 4 test cases and specified the SaveException
AloisHasNeurons Dec 6, 2025
6a4c5b0
Fixed submodules?
AloisHasNeurons Dec 6, 2025
100fe95
add all formatters as class variable
Memeel Dec 6, 2025
07088a8
changed a comment
GreLucie Dec 6, 2025
fcd3db4
Trying to fix indentation in AcademicPagesExporterTest
GreLucie Dec 6, 2025
1efe4a2
Revert change on AcademicPagesExporter
GreLucie Dec 6, 2025
488620d
Fixed some indentation in AcademicPagesExporterTest
GreLucie Dec 6, 2025
5d6e3a2
add all formatters as class variable
Memeel Dec 6, 2025
File filter

Filter by extension

Filter by extension

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

### Added

- We added a custom exporter for academicpages and added the layout format for academic pages. [#12727](https://github.com/JabRef/jabref/issues/12727)
- We added a drop-down menu to those custom fields in the main table for which content selector values exists. [#14087](https://github.com/JabRef/jabref/issues/14087)
- We added a "Jump to Field" dialog (`Ctrl+J`) to quickly search for and navigate to any field across all tabs. [#12276](https://github.com/JabRef/jabref/issues/12276).
- We added "IEEE" as another option for parsing plain text citations. [#14233](github.com/JabRef/jabref/pull/14233)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.jabref.logic.exporter;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.journals.JournalAbbreviationRepository;
import org.jabref.logic.layout.LayoutFormatterPreferences;
import org.jabref.logic.layout.format.HTMLChars;
import org.jabref.logic.layout.format.RemoveLatexCommandsFormatter;
import org.jabref.logic.layout.format.Replace;
import org.jabref.logic.layout.format.SafeFileName;
import org.jabref.logic.util.StandardFileType;
import org.jabref.logic.util.io.FileUtil;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.metadata.SelfContainedSaveOrder;

import org.jspecify.annotations.NonNull;

/**
* A custom exporter to write multiple bib entries as AcademicPages Markdown format.
*/
public class AcademicPagesExporter extends Exporter {
private final String layoutFileFileName;
private final String directory;
private final LayoutFormatterPreferences layoutPreferences;
private final SelfContainedSaveOrder saveOrder;

private final Replace replaceFormatter = new Replace();
private final RemoveLatexCommandsFormatter commandsFormatter = new RemoveLatexCommandsFormatter();
private final HTMLChars htmlFormatter = new HTMLChars();
private final SafeFileName safeFormatter = new SafeFileName();

private TemplateExporter academicPagesTemplate;

/**
* Initialize another export format based on templates stored in directory.
*
*/
public AcademicPagesExporter(LayoutFormatterPreferences layoutPreferences, SelfContainedSaveOrder saveOrder) {
super("academicpages", "academic pages markdowns", StandardFileType.MARKDOWN);
this.layoutFileFileName = "academicpages";
this.directory = "academicpages";
this.layoutPreferences = layoutPreferences;
this.saveOrder = saveOrder;
String consoleName = "academicpages";
this.academicPagesTemplate = new TemplateExporter("academicpages", consoleName, layoutFileFileName, directory, StandardFileType.MARKDOWN, layoutPreferences, saveOrder);
}

@Override
public void export(@NonNull final BibDatabaseContext databaseContext,
@NonNull final Path exportDirectory,
@NonNull List<BibEntry> entries) throws SaveException {
export(databaseContext, exportDirectory, entries, List.of(), JournalAbbreviationLoader.loadBuiltInRepository());
}

/**
* The method that performs the export of all entries by iterating on the entries.
*
* @param databaseContext the database to export from
* @param file the directory to write to
* @param entries a list containing all entries that should be exported
* @param abbreviationRepository the built-in repository
* @throws SaveException Exception thrown if saving goes wrong
*/
@Override
public void export(@NonNull final BibDatabaseContext databaseContext,
@NonNull final Path file,
@NonNull List<BibEntry> entries,
List<Path> fileDirForDataBase,
JournalAbbreviationRepository abbreviationRepository) throws SaveException {
if (entries.isEmpty()) { // Only export if entries exist
return;
}
try {
// convert what the ExportCommand gives as a file parameter to a directory
Path baseDir = file;
String exportDirectoryString = FileUtil.getBaseName(file);
Path exportDirectory = baseDir.getParent().resolve(exportDirectoryString);

// Ensure the directory exists. This is important: AtomicFileWriter will fail if parent dirs are missing.
Files.createDirectories(exportDirectory);

for (BibEntry entry : entries) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could simply switch this to a normal for loop with for (int i =1; i< entiries.length; i++) so you don't need the iterator variable.

// formatting the title of each entry to match the file names format demanded by academic pages (applying the same formatters applied to the title in the academicpages.layout)
Path path = getPath(entry, exportDirectory);

List<BibEntry> individualEntry = new ArrayList<>();
individualEntry.add(entry);
academicPagesTemplate.export(databaseContext, path, individualEntry, fileDirForDataBase, abbreviationRepository);
}
} catch (IOException e) {
throw new SaveException("could not export", e);
}
}

private @NonNull Path getPath(BibEntry entry, Path exportDirectory) {
replaceFormatter.setArgument(" ,-"); // expects an expression that has the character to remove and the replacement character separated by a comma.
String title = entry.getTitle().get();
String formattedTitle = commandsFormatter.format(htmlFormatter.format(replaceFormatter.format(title)));
String safeTitle = safeFormatter.format(formattedTitle);
return exportDirectory.resolve(safeTitle + ".md");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public static ExporterFactory create(CliPreferences preferences) {
exporters.add(new EmbeddedBibFilePdfExporter(bibDatabaseMode, preferences.getCustomEntryTypesRepository(), fieldPreferences));
exporters.add(new CffExporter());
exporters.add(new EndnoteXmlExporter(preferences.getBibEntryPreferences()));
exporters.add(new AcademicPagesExporter(layoutPreferences, saveOrder));

// Now add custom export formats
exporters.addAll(customFormats);
Expand Down
6 changes: 6 additions & 0 deletions jablib/src/main/java/org/jabref/logic/layout/LayoutEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.jabref.logic.layout.format.NonSpaceWhitespaceRemover;
import org.jabref.logic.layout.format.NotFoundFormatter;
import org.jabref.logic.layout.format.Number;
import org.jabref.logic.layout.format.NumberMonthFormatter;
import org.jabref.logic.layout.format.Ordinal;
import org.jabref.logic.layout.format.RTFChars;
import org.jabref.logic.layout.format.RemoveBrackets;
Expand All @@ -77,6 +78,7 @@
import org.jabref.logic.layout.format.RisAuthors;
import org.jabref.logic.layout.format.RisKeywords;
import org.jabref.logic.layout.format.RisMonth;
import org.jabref.logic.layout.format.SafeFileName;
import org.jabref.logic.layout.format.ShortMonthFormatter;
import org.jabref.logic.layout.format.ToLowerCase;
import org.jabref.logic.layout.format.ToUpperCase;
Expand Down Expand Up @@ -565,6 +567,10 @@ private LayoutFormatter getLayoutFormatterByName(String name) {
new ReplaceWithEscapedDoubleQuotes();
case "HayagrivaType" ->
new HayagrivaType();
case "NumberMonth" ->
new NumberMonthFormatter();
case "SafeFileName" ->
new SafeFileName();
default ->
null;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.jabref.logic.layout.format;

import org.jabref.logic.layout.LayoutFormatter;
import org.jabref.model.entry.Month;

/**
* Convert the month name into the corresponding number and return 01 by default
*/
public class NumberMonthFormatter implements LayoutFormatter {

@Override
public String format(String fieldText) {
return Month.parse(fieldText).map(Month::getTwoDigitNumber).orElse("01");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.jabref.logic.layout.format;

import org.jabref.logic.layout.LayoutFormatter;

/**
* Remove all the characters that are not allowed by the OS in file names
*/
public class SafeFileName implements LayoutFormatter {

@Override
public String format(String fieldText) {
return fieldText.replaceAll("[\\\\/:*?\"<>|]", "");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: "\format[RemoveLatexCommands,HTMLChars]{\title}"
collection: publications
category: \format{\entrytype}
permalink: /publication/\format[RemoveLatexCommands,HTMLChars,Replace(\s,-),SafeFileName]{\title}
excerpt: '\begin{note}\format[RemoveLatexCommands,HTMLChars]{\note}\end{note}'
date: \format{\year}-\begin{month}\format[NumberMonth]{\month}\end{month}\begin{!month}01\end{!month}-\begin{day}\format{\day}\end{day}\begin{!day}01\end{!day}
venue: '\format[RemoveLatexCommands,HTMLChars]{\journal}\begin{!journal}Unknown\end{!journal}'
slidesurl: '\begin{file}\format[FileLink(pdf)]{\file}\end{file}\begin{!file}https://[insert username].github.io/files/[insert filename].pdf\end{!file}'
paperurl: '\begin{file}\format[FileLink(pdf)]{\file}\end{file}\begin{!file}https://[insert username].github.io/files/[insert filename].pdf\end{!file}'
bibtexurl: 'https://[insert username].github.io/files/[insert filename].bib'
citation: '\format[HTMLChars]{\author}. (\format{\year}). "&quot;\format[RemoveLatexCommands,HTMLChars]{\title}.&quot; <i>\format[RemoveLatexCommands,HTMLChars]{\journal}</i>.'
---
\begin{abstract}\format{\abstract}\end{abstract}
Loading
Loading