-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix package of PreviewLayout #5702
Changes from 17 commits
820a7e8
046928c
eeb1c27
2d4eb08
f16d690
30e0ac3
fbde17a
be142d5
68b8d0a
6865b13
6b9ce8a
ad392c8
62c7c76
a026538
983aaa2
f6ee3ac
a89b7a1
d72b8dc
c64ce4a
09a4e90
0323f2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Use `public final` instead of getters to offer access to immutable variables | ||
|
||
## Context and Problem Statement | ||
|
||
When making immutable data accessible in a java class, should it be using getters or by non-modifiable fields? | ||
|
||
## Considered Options | ||
|
||
* Offer public static field | ||
* Offer getters | ||
|
||
## Decision Outcome | ||
|
||
Chosen option: "Offer public static field", because getters used to be a convention which was even more manifested due to libraries depending on the existence on getters/setters. In the case of immutable variables, adding public getters is just useless since one is not hiding anything. | ||
|
||
### Positive Consequences | ||
|
||
* Shorter code | ||
|
||
### Negative Consequences | ||
|
||
* new comers could get confused, because getters/setters are still teached |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package org.jabref.logic.bst; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.List; | ||
|
||
import org.jabref.logic.preview.PreviewLayout; | ||
import org.jabref.logic.cleanup.ConvertToBibtexCleanup; | ||
import org.jabref.logic.formatter.bibtexfields.RemoveNewlinesFormatter; | ||
import org.jabref.logic.l10n.Localization; | ||
import org.jabref.logic.layout.format.LatexToUnicodeFormatter; | ||
import org.jabref.logic.layout.format.RemoveLatexCommandsFormatter; | ||
import org.jabref.logic.layout.format.RemoveTilde; | ||
import org.jabref.model.database.BibDatabase; | ||
import org.jabref.model.entry.BibEntry; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class BstPreviewLayout implements PreviewLayout { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(BstPreviewLayout.class); | ||
|
||
private final String name; | ||
|
||
private VM vm; | ||
private String error; | ||
|
||
public BstPreviewLayout(String filename) { | ||
this(Paths.get(filename)); | ||
} | ||
|
||
public BstPreviewLayout(Path path) { | ||
name = path.getFileName().toString(); | ||
if (!Files.exists(path)) { | ||
LOGGER.error("File {} not found", path.toAbsolutePath()); | ||
error = Localization.lang("Error opening file '%0'.", path.toString()); | ||
return; | ||
} | ||
try { | ||
vm = new VM(path.toFile()); | ||
} catch (Exception e) { | ||
LOGGER.error("Could not read {}.", path.toAbsolutePath(), e); | ||
error = Localization.lang("Error opening file '%0'.", path.toString()); | ||
} | ||
} | ||
|
||
@Override | ||
public String generatePreview(BibEntry originalEntry, BibDatabase database) { | ||
if (error != null) { | ||
return error; | ||
} | ||
// ensure that the entry is of BibTeX format (and do not modify the original entry) | ||
BibEntry entry = (BibEntry) originalEntry.clone(); | ||
new ConvertToBibtexCleanup().cleanup(entry); | ||
String result = vm.run(List.of(entry)); | ||
// Remove all comments | ||
result = result.replaceAll("%.*", ""); | ||
// Remove all LaTeX comments | ||
// The RemoveLatexCommandsFormatter keeps the words inside latex environments. Therefore, we remove them manually | ||
result = result.replace("\\begin{thebibliography}{1}", ""); | ||
result = result.replace("\\end{thebibliography}", ""); | ||
// The RemoveLatexCommandsFormatter keeps the word inside the latex command, but we want to remove that completely | ||
result = result.replaceAll("\\\\bibitem[{].*[}]", ""); | ||
// We want to replace \newblock by a space instead of completely removing it | ||
result = result.replace("\\newblock", " "); | ||
// remove all latex commands statements - assumption: command in a separate line | ||
result = result.replaceAll("(?m)^\\\\.*$", ""); | ||
// remove some IEEEtran.bst output (resulting from a multiline \providecommand) | ||
result = result.replace("#2}}", ""); | ||
// Have quotes right - and more | ||
result = new LatexToUnicodeFormatter().format(result); | ||
result = result.replace("``", "\""); | ||
result = result.replace("''", "\""); | ||
// Final cleanup | ||
result = new RemoveNewlinesFormatter().format(result); | ||
result = new RemoveLatexCommandsFormatter().format(result); | ||
result = new RemoveTilde().format(result); | ||
result = result.trim().replaceAll(" +", " "); | ||
return result; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return name; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -270,7 +270,7 @@ private VM(CommonTree tree) { | |
if (context == null) { | ||
throw new VMException("Call.type$ can only be called from within a context (ITERATE or REVERSE)."); | ||
} | ||
VM.this.execute(context.getBibtexEntry().getType().getName(), context); | ||
VM.this.execute(context.entry.getType().getName(), context); | ||
}); | ||
|
||
buildInFunctions.put("change.case$", new ChangeCaseFunction(this)); | ||
|
@@ -303,7 +303,7 @@ private VM(CommonTree tree) { | |
if (context == null) { | ||
throw new VMException("Must have an entry to cite$"); | ||
} | ||
stack.push(context.getBibtexEntry().getCiteKeyOptional().orElse(null)); | ||
stack.push(context.entry.getCiteKeyOptional().orElse(null)); | ||
}); | ||
|
||
/* | ||
|
@@ -581,7 +581,7 @@ private VM(CommonTree tree) { | |
throw new VMException("type$ need a context."); | ||
} | ||
|
||
stack.push(context.getBibtexEntry().getType().getName()); | ||
stack.push(context.entry.getType().getName()); | ||
}); | ||
|
||
/* | ||
|
@@ -843,11 +843,14 @@ public String run(Collection<BibEntry> bibtex) { | |
} | ||
|
||
/** | ||
* @param bibtex list of entries to convert | ||
* Transforms the given list of BibEntries to a rendered list of references using the underlying bst file | ||
* | ||
* @param bibEntries list of entries to convert | ||
* @param bibDatabase (may be null) the bibDatabase used for resolving strings / crossref | ||
* @return list of references in plain text form | ||
*/ | ||
public String run(Collection<BibEntry> bibtex, BibDatabase bibDatabase) { | ||
Objects.requireNonNull(bibtex); | ||
public String run(Collection<BibEntry> bibEntries, BibDatabase bibDatabase) { | ||
Objects.requireNonNull(bibEntries); | ||
|
||
// Reset | ||
bbl = new StringBuilder(); | ||
|
@@ -864,8 +867,8 @@ public String run(Collection<BibEntry> bibtex, BibDatabase bibDatabase) { | |
stack = new Stack<>(); | ||
|
||
// Create entries | ||
entries = new ArrayList<>(bibtex.size()); | ||
for (BibEntry entry : bibtex) { | ||
entries = new ArrayList<>(bibEntries.size()); | ||
for (BibEntry entry : bibEntries) { | ||
entries.add(new BstEntry(entry)); | ||
} | ||
|
||
|
@@ -922,16 +925,16 @@ public String run(Collection<BibEntry> bibtex, BibDatabase bibDatabase) { | |
*/ | ||
private void read(BibDatabase bibDatabase) { | ||
for (BstEntry e : entries) { | ||
for (Map.Entry<String, String> mEntry : e.getFields().entrySet()) { | ||
for (Map.Entry<String, String> mEntry : e.fields.entrySet()) { | ||
Field field = FieldFactory.parseField(mEntry.getKey()); | ||
String fieldValue = e.getBibtexEntry().getResolvedFieldOrAlias(field, bibDatabase).orElse(null); | ||
String fieldValue = e.entry.getResolvedFieldOrAlias(field, bibDatabase).orElse(null); | ||
mEntry.setValue(fieldValue); | ||
} | ||
} | ||
|
||
for (BstEntry e : entries) { | ||
if (!e.getFields().containsKey(StandardField.CROSSREF.getName())) { | ||
e.getFields().put(StandardField.CROSSREF.getName(), null); | ||
if (!e.fields.containsKey(StandardField.CROSSREF.getName())) { | ||
e.fields.put(StandardField.CROSSREF.getName(), null); | ||
} | ||
} | ||
} | ||
|
@@ -978,7 +981,7 @@ private void entry(Tree child) { | |
String name = t.getChild(i).getText(); | ||
|
||
for (BstEntry entry : entries) { | ||
entry.getFields().put(name, null); | ||
entry.fields.put(name, null); | ||
} | ||
} | ||
|
||
|
@@ -1103,8 +1106,8 @@ private void execute(String name, BstEntry context) { | |
|
||
if (context != null) { | ||
|
||
if (context.getFields().containsKey(name)) { | ||
stack.push(context.getFields().get(name)); | ||
if (context.fields.containsKey(name)) { | ||
stack.push(context.fields.get(name)); | ||
return; | ||
} | ||
if (context.localStrings.containsKey(name)) { | ||
|
@@ -1171,25 +1174,17 @@ private void strings(Tree child) { | |
|
||
public static class BstEntry { | ||
|
||
private final BibEntry entry; | ||
public final BibEntry entry; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then this triggers a follow-up question (@LinusDietz): is it ok to make variables with mutable types (like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is effective Java #39. "Make defensive copies when needed".
However, did not see that being done much, so I am curios to the opinion of @LinusDietz |
||
|
||
private final Map<String, String> localStrings = new HashMap<>(); | ||
public final Map<String, String> localStrings = new HashMap<>(); | ||
|
||
private final Map<String, String> fields = new HashMap<>(); | ||
public final Map<String, String> fields = new HashMap<>(); | ||
|
||
private final Map<String, Integer> localIntegers = new HashMap<>(); | ||
public final Map<String, Integer> localIntegers = new HashMap<>(); | ||
|
||
public BstEntry(BibEntry e) { | ||
this.entry = e; | ||
} | ||
|
||
public Map<String, String> getFields() { | ||
return fields; | ||
} | ||
|
||
public BibEntry getBibtexEntry() { | ||
return entry; | ||
} | ||
} | ||
|
||
private void push(Integer integer) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move this also to the
citationstyle
package, because it's not really aboutbst
(which is only used as a tool)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see
org.jabref.logic.preview
as the other possibility to collect the preview generators. -- I would keep the packageorg.jabref.logic.citationstyle
for CSL only and keep out the relation to.bst
and to our other Layouts.