From de0131cc8898d3de3478684dbd46dbd3998288f8 Mon Sep 17 00:00:00 2001 From: Joerg Lenhard Date: Fri, 29 Jul 2016 10:30:26 +0200 Subject: [PATCH 1/2] Kep @Comment text in a bib file --- CHANGELOG.md | 1 + .../importer/fileformat/BibtexParser.java | 59 ++++++++----------- .../net/sf/jabref/model/entry/BibEntry.java | 2 +- .../importer/fileformat/BibtexParserTest.java | 54 +++++++++++++++++ .../bibWithUserCommentAndEntryChange.bib | 7 +++ .../resources/testbib/bibWithUserComments.bib | 7 +++ 6 files changed, 96 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a47031a6961..21fe45e53d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - [#1345](https://github.com/JabRef/jabref/issues/1345) Cleanup ISSN ### Fixed +- Fixed [#1632](https://github.com/JabRef/jabref/issues/1632) User comments (@Comment) with or without brackets are now kept - Fixed [#1264](https://github.com/JabRef/jabref/issues/1264): S with caron does not render correctly - LaTeX to Unicode converter now handles combining accents - Fixed [#636](https://github.com/JabRef/jabref/issues/636): DOI in export filters diff --git a/src/main/java/net/sf/jabref/importer/fileformat/BibtexParser.java b/src/main/java/net/sf/jabref/importer/fileformat/BibtexParser.java index 89df2b6d03d..918212f4d56 100644 --- a/src/main/java/net/sf/jabref/importer/fileformat/BibtexParser.java +++ b/src/main/java/net/sf/jabref/importer/fileformat/BibtexParser.java @@ -243,22 +243,18 @@ private void parseAndAddEntry(String type) { } private void parseJabRefComment(Map meta) throws IOException { - StringBuilder buffer = parseBracketedTextExactly(); - /** - * - * Metadata are used to store Bibkeeper-specific - * information in .bib files. - * - * Metadata are stored in bibtex files in the format - * - * @comment{jabref-meta: type:data0;data1;data2;...} - * - * Each comment that starts with the META_FLAG is stored - * in the meta HashMap, with type as key. Unluckily, the - * old META_FLAG bibkeeper-meta: was used in JabRef 1.0 - * and 1.1, so we need to support it as well. At least - * for a while. We'll always save with the new one. - */ + StringBuilder buffer = null; + try { + buffer = parseBracketedTextExactly(); + } catch (IOException e) { + /* if we get an IO Exception here, than we have an unbracketed comment, + * which means that we should just return and the comment will be picked up as arbitrary text + * by the parser + */ + LOGGER.info("Found unbracketed comment"); + return; + } + String comment = buffer.toString().replaceAll("[\\x0d\\x0a]", ""); if (comment.substring(0, Math.min(comment.length(), MetaData.META_FLAG.length())).equals( @@ -297,11 +293,8 @@ private void parseJabRefComment(Map meta) throws IOException { // custom entry types are always re-written by JabRef and not stored in the file dumpTextReadSoFarToString(); - } else { - // FIXME: user comments are simply dropped - // at least, we log that we ignored the comment - LOGGER.info("Dropped comment from database: " + comment); } + } @@ -329,14 +322,14 @@ private String dumpTextReadSoFarToString() { // if there is no entry found, simply return the content (necessary to parse text remaining after the last entry) if (indexOfAt == -1) { return purgeEOFCharacters(result); - } else if(result.contains(SavePreferences.ENCODING_PREFIX)) { + } else if (result.contains(SavePreferences.ENCODING_PREFIX)) { // purge the encoding line if it exists int runningIndex = result.indexOf(SavePreferences.ENCODING_PREFIX); - while(runningIndex < indexOfAt) { - if(result.charAt(runningIndex) == '\n') { + while (runningIndex < indexOfAt) { + if (result.charAt(runningIndex) == '\n') { break; - } else if(result.charAt(runningIndex) == '\r') { - if(result.charAt(runningIndex + 1) == '\n') { + } else if (result.charAt(runningIndex) == '\r') { + if (result.charAt(runningIndex + 1) == '\n') { runningIndex++; } break; @@ -413,10 +406,10 @@ private void skipSpace() throws IOException { private void skipOneNewline() throws IOException { skipSpace(); - if(peek() == '\r') { + if (peek() == '\r') { read(); } - if(peek() == '\n') { + if (peek() == '\n') { read(); } } @@ -460,7 +453,7 @@ private int peek() throws IOException { private int read() throws IOException { int character = pushbackReader.read(); - if(! isEOFCharacter(character)) { + if (!isEOFCharacter(character)) { pureTextFromFile.offerLast((char) character); } if (character == '\n') { @@ -474,7 +467,7 @@ private void unread(int character) throws IOException { line--; } pushbackReader.unread(character); - if(pureTextFromFile.getLast() == character) { + if (pureTextFromFile.getLast() == character) { pureTextFromFile.pollLast(); } } @@ -799,7 +792,7 @@ private String parseKey() throws IOException { private StringBuffer parseBracketedText() throws IOException { StringBuffer value = new StringBuffer(); - consume('{','('); + consume('{', '('); int brackets = 0; @@ -834,18 +827,18 @@ private StringBuffer parseBracketedText() throws IOException { } } - consume('}',')'); + consume('}', ')'); return value; } - private boolean isClosingBracketNext () { + private boolean isClosingBracketNext() { try { int peek = peek(); boolean isCurlyBracket = peek == '}'; boolean isRoundBracket = peek == ')'; return isCurlyBracket || isRoundBracket; - } catch(IOException e) { + } catch (IOException e) { return false; } } diff --git a/src/main/java/net/sf/jabref/model/entry/BibEntry.java b/src/main/java/net/sf/jabref/model/entry/BibEntry.java index b98ca995825..aab3c15cd47 100644 --- a/src/main/java/net/sf/jabref/model/entry/BibEntry.java +++ b/src/main/java/net/sf/jabref/model/entry/BibEntry.java @@ -634,7 +634,7 @@ public String getUserComments() { try { // get the text before the entry - String prolog = parsedSerialization.substring(0, parsedSerialization.indexOf('@')); + String prolog = parsedSerialization.substring(0, parsedSerialization.lastIndexOf('@')); // delete trailing whitespaces (between entry and text) prolog = prolog.replaceFirst("\\s+$", ""); diff --git a/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java b/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java index da4eebee43c..f1124b11fc4 100644 --- a/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java +++ b/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java @@ -1556,4 +1556,58 @@ public void preserveEncodingPrefixInsideEntry() { assertEquals(Collections.singletonList(expected), parsed); } + @Test + public void parseBracketedComment() throws IOException { + String commentText = "@Comment{someComment}"; + ParserResult result = BibtexParser.parse(new StringReader(commentText)); + + assertEquals(commentText, result.getDatabase().getEpilog()); + } + + @Test + public void parseRegularCommentBeforeEntry() throws IOException { + // @formatter:off + String bibtexEntry = "@Comment{someComment} " + OS.NEWLINE + + "@Article{test," + OS.NEWLINE + + " Author = {Foo Bar}," + OS.NEWLINE + + " Journal = {International Journal of Something}," + OS.NEWLINE + + " Note = {some note}," + OS.NEWLINE + + " Number = {1}" + OS.NEWLINE + + "}"; + // @formatter:on + + ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry)); + Collection entries = result.getDatabase().getEntries(); + BibEntry entry = entries.iterator().next(); + + assertEquals(bibtexEntry, entry.getParsedSerialization()); + } + + @Test + public void parseCommentWithoutBrackets () throws IOException { + String commentText = "@Comment someComment"; + ParserResult result = BibtexParser.parse(new StringReader(commentText)); + + assertEquals(commentText, result.getDatabase().getEpilog()); + } + + @Test + public void parseCommentWithoutBracketsBeforeEntry() throws IOException { + // @formatter:off + String bibtexEntry = "@Comment someComment " + OS.NEWLINE + + "@Article{test," + OS.NEWLINE + + " Author = {Foo Bar}," + OS.NEWLINE + + " Journal = {International Journal of Something}," + OS.NEWLINE + + " Note = {some note}," + OS.NEWLINE + + " Number = {1}" + OS.NEWLINE + + "}"; + // @formatter:on + + ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry)); + Collection entries = result.getDatabase().getEntries(); + BibEntry entry = entries.iterator().next(); + + assertEquals(bibtexEntry, entry.getParsedSerialization()); + } + } diff --git a/src/test/resources/testbib/bibWithUserCommentAndEntryChange.bib b/src/test/resources/testbib/bibWithUserCommentAndEntryChange.bib index ea17f6aaae5..64df3fa78b8 100644 --- a/src/test/resources/testbib/bibWithUserCommentAndEntryChange.bib +++ b/src/test/resources/testbib/bibWithUserCommentAndEntryChange.bib @@ -5,6 +5,11 @@ @Preamble{preamble @String{firstString = {my first string}} @String{secondString = {}} +@Comment { this is a bracketed comment that should be preserved + +Regardless auf how much space there is inbetween +} + @ARTICLE{1102917, author = {E. Bardram}, title = {The trouble with login: on usability and computer security in ubiquitous @@ -21,6 +26,8 @@ @ARTICLE{1102917 publisher = {Springer-Verlag} } +@Comment this in an unbracketed comment that should be preserved as well + This is some arbitrary user comment that should be preserved @InProceedings{1137631, diff --git a/src/test/resources/testbib/bibWithUserComments.bib b/src/test/resources/testbib/bibWithUserComments.bib index 8148c3b6d63..90685b10eac 100644 --- a/src/test/resources/testbib/bibWithUserComments.bib +++ b/src/test/resources/testbib/bibWithUserComments.bib @@ -5,6 +5,11 @@ @Preamble{preamble @String{firstString = {my first string}} @String{secondString = {}} +@Comment { this is a bracketed comment that should be preserved + +Regardless auf how much space there is inbetween +} + @ARTICLE{1102917, author = {E. Bardram}, title = {The trouble with login: on usability and computer security in ubiquitous @@ -21,6 +26,8 @@ @ARTICLE{1102917 publisher = {Springer-Verlag} } +@Comment this in an unbracketed comment that should be preserved as well + This is some arbitrary user comment that should be preserved @INPROCEEDINGS{1137631, From 071f2a14f356e90004c77bb05a4324d34c624caf Mon Sep 17 00:00:00 2001 From: Joerg Lenhard Date: Fri, 29 Jul 2016 10:56:57 +0200 Subject: [PATCH 2/2] Add test for @Comment that contains regular entries --- .../importer/fileformat/BibtexParserTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java b/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java index f1124b11fc4..eca39f20a5a 100644 --- a/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java +++ b/src/test/java/net/sf/jabref/importer/fileformat/BibtexParserTest.java @@ -1610,4 +1610,25 @@ public void parseCommentWithoutBracketsBeforeEntry() throws IOException { assertEquals(bibtexEntry, entry.getParsedSerialization()); } + @Test + public void parseCommentContainingEntries() throws IOException { + // @formatter:off + String bibtexEntry = "@Comment{@article{myarticle,}" + OS.NEWLINE + + "@inproceedings{blabla, title={the proceedings of blabla}; }" + OS.NEWLINE + + "} " + OS.NEWLINE + + "@Article{test," + OS.NEWLINE + + " Author = {Foo Bar}," + OS.NEWLINE + + " Journal = {International Journal of Something}," + OS.NEWLINE + + " Note = {some note}," + OS.NEWLINE + + " Number = {1}" + OS.NEWLINE + + "}"; + // @formatter:on + + ParserResult result = BibtexParser.parse(new StringReader(bibtexEntry)); + Collection entries = result.getDatabase().getEntries(); + BibEntry entry = entries.iterator().next(); + + assertEquals(bibtexEntry, entry.getParsedSerialization()); + } + }