Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into fix/ui-improvement-…
Browse files Browse the repository at this point in the history
…in-protected-terms-files

* upstream/main:
  Update src/main/java/org/jabref/logic/exporter/AtomicFileOutputStream.java
  Fix saving on network drive under macOS
  Infer DOI from ArXiv identifier (#10449)
  Add TexShop Icon (#10447)
  Fix PDF export (#10361)
  Fixed SpringerFetcherTest and ACMPortalFetcherTest (#10445)
  Bump org.openrewrite.rewrite from 6.3.11 to 6.3.16 (#10442)
  Update all of lucene
  Bump org.apache.lucene:lucene-core from 9.7.0 to 9.8.0
  Bump com.dlsc.gemsfx:gemsfx from 1.77.0 to 1.82.0
  Accept LaTeX errors in comment field (#10436)
  fix checkstyle
  fix escaping of slashes
  fix checkstyle  and l10n
  Add TeXShop (macOS only)
  • Loading branch information
Siedlerchr committed Oct 8, 2023
2 parents ba9be75 + ca00d64 commit 46bad1d
Show file tree
Hide file tree
Showing 21 changed files with 398 additions and 144 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We added a link "Get more themes..." in the preferences to that points to [themes.jabref.org](https://themes.jabref.org) allowing the user to download new themes. [#10243](https://github.com/JabRef/jabref/issues/10243)
- We added a fetcher for [LOBID](https://lobid.org/resources/api) resources. [koppor#386](https://github.com/koppor/jabref/issues/386)
- When in `biblatex` mode, the [integrity check](https://docs.jabref.org/finding-sorting-and-cleaning-entries/checkintegrity) for journal titles now also checks the field `journal`.
- We added support for pushing citations to [TeXShop](https://pages.uoregon.edu/koch/texshop/) on macOS [forum#2699](https://discourse.jabref.org/t/push-to-texshop-mac/2699).

### Changed

- The export formats `listrefs`, `tablerefs`, `tablerefsabsbib`, now use the ISO date format in the footer [#10383](https://github.com/JabRef/jabref/pull/10383).
- When searching for an identifier in the "Web search", the title of the search window is now "Identifier-based Web Search". [#10391](https://github.com/JabRef/jabref/pull/10391)
- The ampersand checker now skips verbatim fields (`file`, `url`, ...). [#10419](https://github.com/JabRef/jabref/pull/10419)
- If no existing document is selected for exporting "XMP annotated pdf" JabRef will now create a new PDF file with a sample text and the metadata. [#10102](https://github.com/JabRef/jabref/issues/10102)
- We modified the DOI cleanup to infer the DOI from an ArXiV ID if it's present. [10426](https://github.com/JabRef/jabref/issues/10426)

### Fixed

Expand All @@ -37,6 +40,8 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We fixed an issue where it was possible to create a group with no name or with a group separator inside the name [#9776](https://github.com/JabRef/jabref/issues/9776)
- Biblatex's `journaltitle` is now also respected for showing the journal information. [#10397](https://github.com/JabRef/jabref/issues/10397)
- JabRef does not hang anymore when exporting via CLI. [#10380](https://github.com/JabRef/jabref/issues/10380)
- We fixed an issue where it was not possible to save a library on a network share under macOS due to an exception when acquiring a file lock [#10452](https://github.com/JabRef/jabref/issues/10452)
- We fixed an issue where exporting "XMP annotated pdf" without selecting an existing document would produce an exception. [#10102](https://github.com/JabRef/jabref/issues/10102)

### Removed

Expand Down
14 changes: 7 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ plugins {

id 'idea'

id 'org.openrewrite.rewrite' version '6.3.11'
id 'org.openrewrite.rewrite' version '6.3.16'
}

// Enable following for debugging
Expand Down Expand Up @@ -115,11 +115,11 @@ dependencies {
implementation 'org.apache.pdfbox:fontbox:3.0.0'
implementation 'org.apache.pdfbox:xmpbox:3.0.0'

implementation 'org.apache.lucene:lucene-core:9.7.0'
implementation 'org.apache.lucene:lucene-queryparser:9.7.0'
implementation 'org.apache.lucene:lucene-queries:9.7.0'
implementation 'org.apache.lucene:lucene-analysis-common:9.7.0'
implementation 'org.apache.lucene:lucene-highlighter:9.7.0'
implementation 'org.apache.lucene:lucene-core:9.8.0'
implementation 'org.apache.lucene:lucene-queryparser:9.8.0'
implementation 'org.apache.lucene:lucene-queries:9.8.0'
implementation 'org.apache.lucene:lucene-analysis-common:9.8.0'
implementation 'org.apache.lucene:lucene-highlighter:9.8.0'

implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.10.0'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.13.0'
Expand Down Expand Up @@ -170,7 +170,7 @@ dependencies {
implementation('com.tobiasdiez:easybind:2.2.1-SNAPSHOT')
implementation 'org.fxmisc.flowless:flowless:0.7.1'
implementation 'org.fxmisc.richtext:richtextfx:0.11.1'
implementation (group: 'com.dlsc.gemsfx', name: 'gemsfx', version: '1.77.0') {
implementation (group: 'com.dlsc.gemsfx', name: 'gemsfx', version: '1.82.0') {
exclude module: 'javax.inject' // Split package, use only jakarta.inject
exclude group: 'org.apache.logging.log4j'
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/icon/IconTheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ public enum JabRefIcons implements JabRefIcon {
APPLICATION_VIM(JabRefMaterialDesignIcon.VIM),
APPLICATION_WINEDT(JabRefMaterialDesignIcon.WINEDT),
APPLICATION_SUBLIMETEXT(JabRefMaterialDesignIcon.SUBLIME_TEXT),
APPLICATION_TEXSHOP(JabRefMaterialDesignIcon.TEXSHOP),
KEY_BINDINGS(MaterialDesignK.KEYBOARD),
FIND_DUPLICATES(MaterialDesignC.CODE_EQUAL),
CONNECT_DB(MaterialDesignC.CLOUD_UPLOAD),
Expand Down Expand Up @@ -351,7 +352,6 @@ public enum JabRefIcons implements JabRefIcon {
ACCEPT_LEFT(MaterialDesignS.SUBDIRECTORY_ARROW_LEFT),
ACCEPT_RIGHT(MaterialDesignS.SUBDIRECTORY_ARROW_RIGHT),
MERGE_GROUPS(MaterialDesignS.SOURCE_MERGE);

private final JabRefIcon icon;

JabRefIcons(Ikon... icons) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public enum JabRefMaterialDesignIcon implements Ikon {
SET_ALL("jab-setall", '\ue90c'),
VSCODE("jab-vsvode", '\ue90d'),
CANCEL("jab-cancel", '\ue90e'),
SUBLIME_TEXT("jab-sublime-text", '\ue90f');
SUBLIME_TEXT("jab-sublime-text", '\ue90f'),
TEXSHOP("jab-texshop", '\ue910');

private String description;
private int code;
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/jabref/gui/push/PushToApplications.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class PushToApplications {
public static final String VIM = "Vim";
public static final String WIN_EDT = "WinEdt";
public static final String SUBLIME_TEXT = "Sublime Text";
public static final String TEXSHOP = "TeXShop";

private static final List<PushToApplication> APPLICATIONS = new ArrayList<>();

Expand All @@ -34,7 +35,8 @@ public static List<PushToApplication> getAllApplications(DialogService dialogSer
new PushToTexmaker(dialogService, preferencesService),
new PushToTeXstudio(dialogService, preferencesService),
new PushToVim(dialogService, preferencesService),
new PushToWinEdt(dialogService, preferencesService)));
new PushToWinEdt(dialogService, preferencesService),
new PushToTexShop(dialogService, preferencesService)));

return APPLICATIONS;
}
Expand Down
1 change: 0 additions & 1 deletion src/main/java/org/jabref/gui/push/PushToSublimeText.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public void pushEntries(BibDatabaseContext database, List<BibEntry> entries, Str
return;
}
try {

LOGGER.debug("Sublime string: {}", String.join(" ", getCommandLine(keyString)));
ProcessBuilder processBuilder = new ProcessBuilder(getCommandLine(keyString));
processBuilder.inheritIO();
Expand Down
85 changes: 85 additions & 0 deletions src/main/java/org/jabref/gui/push/PushToTexShop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.jabref.gui.push;

import java.io.IOException;
import java.util.List;

import org.jabref.gui.DialogService;
import org.jabref.gui.JabRefExecutorService;
import org.jabref.gui.icon.IconTheme;
import org.jabref.gui.icon.JabRefIcon;
import org.jabref.gui.util.StreamGobbler;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.OS;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.PreferencesService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PushToTexShop extends AbstractPushToApplication {

public static final String NAME = PushToApplications.TEXSHOP;

private static final Logger LOGGER = LoggerFactory.getLogger(PushToTexShop.class);

public PushToTexShop(DialogService dialogService, PreferencesService preferencesService) {
super(dialogService, preferencesService);
}

@Override
public String getDisplayName() {
return NAME;
}

@Override
public JabRefIcon getApplicationIcon() {
return IconTheme.JabRefIcons.APPLICATION_TEXSHOP;
}

@Override
public void pushEntries(BibDatabaseContext database, List<BibEntry> entries, String keyString) {
couldNotPush = false;
couldNotCall = false;
notDefined = false;

commandPath = preferencesService.getPushToApplicationPreferences().getCommandPaths().get(this.getDisplayName());

try {
LOGGER.debug("TexShop string: {}", String.join(" ", getCommandLine(keyString)));
ProcessBuilder processBuilder = new ProcessBuilder(getCommandLine(keyString));
processBuilder.inheritIO();
Process process = processBuilder.start();
StreamGobbler streamGobblerInput = new StreamGobbler(process.getInputStream(), LOGGER::info);
StreamGobbler streamGobblerError = new StreamGobbler(process.getErrorStream(), LOGGER::info);

JabRefExecutorService.INSTANCE.execute(streamGobblerInput);
JabRefExecutorService.INSTANCE.execute(streamGobblerError);
} catch (IOException excep) {
LOGGER.warn("Error: Could not call executable '{}'", commandPath, excep);
couldNotCall = true;
}
}

@Override
protected String[] getCommandLine(String keyString) {
String citeCommand = getCitePrefix();
// we need to escape the extra slashses
if (getCitePrefix().contains("\\")) {
citeCommand = "\"\\" + getCitePrefix();
}

String osascriptTexShop = "osascript -e 'tell application \"TeXShop\"\n" +
"activate\n" +
"set TheString to " + citeCommand + keyString + getCiteSuffix() + "\"\n" +
"set content of selection of front document to TheString\n" +
"end tell'";

if (OS.OS_X) {
return new String[] {"sh", "-c", osascriptTexShop};
} else {
dialogService.showInformationDialogAndWait(Localization.lang("Push to application"), Localization.lang("Pushing citations to TeXShop is only possible on macOS!"));
return new String[] {};
}
}
}
19 changes: 16 additions & 3 deletions src/main/java/org/jabref/logic/cleanup/DoiCleanup.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@
import org.jabref.model.entry.field.Field;
import org.jabref.model.entry.field.StandardField;
import org.jabref.model.entry.field.UnknownField;
import org.jabref.model.entry.identifier.ArXivIdentifier;
import org.jabref.model.entry.identifier.DOI;

/**
* Formats the DOI (e.g. removes http part) and also moves DOIs from note, url or ee field to the doi field.
* Formats the DOI (e.g. removes http part) and also infers DOIs from the note, url, eprint or ee fields.
*/
public class DoiCleanup implements CleanupJob {

/**
* Fields to check for DOIs.
*/
private static final List<Field> FIELDS = Arrays.asList(StandardField.NOTE, StandardField.URL, new UnknownField("ee"));
private static final List<Field> FIELDS = Arrays.asList(StandardField.NOTE, StandardField.URL, StandardField.EPRINT,
new UnknownField("ee"));

@Override
public List<FieldChange> cleanup(BibEntry entry) {
Expand Down Expand Up @@ -57,14 +59,25 @@ public List<FieldChange> cleanup(BibEntry entry) {
} else {
// As the Doi field is empty we now check if note, url, or ee field contains a Doi
for (Field field : FIELDS) {
Optional<DOI> doi = entry.getField(field).flatMap(DOI::parse);
Optional<String> fieldContentOpt = entry.getField(field);

Optional<DOI> doi = fieldContentOpt.flatMap(DOI::parse);

if (doi.isPresent()) {
// Update Doi
Optional<FieldChange> change = entry.setField(StandardField.DOI, doi.get().getDOI());
change.ifPresent(changes::add);
removeFieldValue(entry, field, changes);
}

if (StandardField.EPRINT == field) {
fieldContentOpt.flatMap(ArXivIdentifier::parse)
.flatMap(ArXivIdentifier::inferDOI)
.ifPresent(inferredDoi -> {
Optional<FieldChange> change = entry.setField(StandardField.DOI, inferredDoi.getDOI());
change.ifPresent(changes::add);
});
}
}
}
return changes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class AtomicFileOutputStream extends FilterOutputStream {
*/
private final Path temporaryFile;

private final FileLock temporaryFileLock;
private FileLock temporaryFileLock;

/**
* A backup of the target file (if it exists), created when the stream is closed
Expand Down Expand Up @@ -106,7 +106,13 @@ public AtomicFileOutputStream(Path path) throws IOException {
try {
// Lock files (so that at least not another JabRef instance writes at the same time to the same tmp file)
if (out instanceof FileOutputStream stream) {
temporaryFileLock = stream.getChannel().lock();
try {
temporaryFileLock = stream.getChannel().tryLock();
} catch (IOException ex) {
// workaround for https://bugs.openjdk.org/browse/JDK-8167023
LOGGER.warn("Could not acquire file lock. Maybe we are on a network drive?", ex);
temporaryFileLock = null;
}
} else {
temporaryFileLock = null;
}
Expand Down
27 changes: 26 additions & 1 deletion src/main/java/org/jabref/logic/exporter/XmpPdfExporter.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jabref.logic.exporter;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
Expand All @@ -11,6 +13,12 @@
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;

public class XmpPdfExporter extends Exporter {

private final XmpPreferences xmpPreferences;
Expand All @@ -26,7 +34,24 @@ public void export(BibDatabaseContext databaseContext, Path pdfFile, List<BibEnt
Objects.requireNonNull(pdfFile);
Objects.requireNonNull(entries);

if (pdfFile.toString().endsWith(".pdf")) {
Path filePath = pdfFile.toAbsolutePath();

if (!Files.exists(filePath)) {
try (PDDocument document = new PDDocument()) {
PDPage page = new PDPage();
document.addPage(page);

try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
contentStream.beginText();
contentStream.newLineAtOffset(25, 500);
contentStream.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA), 12);
contentStream.showText("This PDF was created by JabRef. It demonstrates the embedding of XMP data in PDF files. Please open the file metadata view of your PDF viewer to see the attached files. Note that the normal usage is to embed the BibTeX data in an existing PDF.");
contentStream.endText();
}
document.save(filePath.toString());
} catch (IOException e) {
throw new Exception("Error creating PDF", e);
}
new XmpUtilWriter(xmpPreferences).writeXmp(pdfFile, entries, databaseContext.getDatabase());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
/**
* Checks if the BibEntry contains unescaped ampersands.
* This is done in nonverbatim fields. Similar to {@link HTMLCharacterChecker}
*
* The {@link LatexIntegrityChecker} is not able to check unescaped ampersands. Therefore, this separate checker is required.
*/
public class AmpersandChecker implements EntryChecker {
// matches for an & preceded by any number of \
Expand Down
Loading

0 comments on commit 46bad1d

Please sign in to comment.