diff --git a/src/main/java/com/orgzly/org/parser/OrgParserWriter.java b/src/main/java/com/orgzly/org/parser/OrgParserWriter.java index dccf5d7..ec0b0a7 100644 --- a/src/main/java/com/orgzly/org/parser/OrgParserWriter.java +++ b/src/main/java/com/orgzly/org/parser/OrgParserWriter.java @@ -204,11 +204,13 @@ public String whiteSpacedHead(OrgHead head, int level, boolean isIndented) { if (head.hasContent()) { /* * Separate content from header with an empty line, - * unless it starts with following strings. + * unless it starts with following strings or a custom drawer. * Until LOGBOOK and CLOCK support is added. */ String content = head.getContent().trim(); - if (!content.startsWith(":LOGBOOK:") && !content.startsWith("CLOCK: ") && !isLogNoteHeading(content)) { + String firstLine = content.split("\n")[0].trim(); + if (!content.startsWith(":LOGBOOK:") && !content.startsWith("CLOCK: ") + && !isLogNoteHeading(content) && !lineStartswithDrawer(firstLine)) { if (settings.separateHeaderAndContentWithNewLine) { s.append("\n"); } @@ -260,6 +262,11 @@ private boolean isLogNoteHeading(String content) { return false; } + private boolean lineStartswithDrawer(String line) { + // example of a drawer: :BACKLINKS: + return line.startsWith(":") && line.endsWith(":"); + } + /** Append (level + 1) spaces. */ private void appendIndent(StringBuilder s, int level, boolean isIndented) { if (isIndented) { diff --git a/src/test/java/com/orgzly/org/parser/OrgParserTest.java b/src/test/java/com/orgzly/org/parser/OrgParserTest.java index cdacf4d..7941073 100644 --- a/src/test/java/com/orgzly/org/parser/OrgParserTest.java +++ b/src/test/java/com/orgzly/org/parser/OrgParserTest.java @@ -405,6 +405,39 @@ public void testNoteBodyNote() { Assert.assertEquals("* Title 1\n\n\n\nContent\n\n* Title 2\n", out); } + @Test + public void testSeparateHeaderDrawerContent1() throws Exception { + // test that we don't prepend content with a newline if content starts with a drawer + // fixes https://github.com/orgzly-revived/orgzly-android-revived/issues/95 + OrgParserSettings settings = new OrgParserSettings(); + settings.separateHeaderAndContentWithNewLine = true; + parserWriter = new OrgParserWriter(settings); + + OrgHead head1 = new OrgHead("Title 1"); + head1.setContent(":SOMEDRAWER:\nfoo\n:END:\n\nContent"); + OrgNodeInList nodeInList1 = new OrgNodeInList(1, 1, head1); + + String out = parserWriter.whiteSpacedFilePreface("") + parserWriter.whiteSpacedHead(nodeInList1, false); + Assert.assertEquals("* Title 1\n:SOMEDRAWER:\nfoo\n:END:\n\nContent\n\n", out); + // although `separateHeaderAndContentWithNewLine` is true, we don't expect extra new line at the end of the drawer + // since custom drawers are part of the content, which we currently don't modify during export + } + + @Test + public void testSeparateHeaderDrawerContent0() throws Exception { + // test that we don't prepend content with a newline if content starts with a drawer + OrgParserSettings settings = new OrgParserSettings(); + settings.separateHeaderAndContentWithNewLine = false; + parserWriter = new OrgParserWriter(settings); + + OrgHead head1 = new OrgHead("Title 1"); + head1.setContent(":SOMEDRAWER:\nfoo\n:END:\nContent"); + OrgNodeInList nodeInList1 = new OrgNodeInList(1, 1, head1); + + String out = parserWriter.whiteSpacedFilePreface("") + parserWriter.whiteSpacedHead(nodeInList1, false); + Assert.assertEquals("* Title 1\n:SOMEDRAWER:\nfoo\n:END:\nContent\n\n", out); + } + @Test public void testNotSeparateHeaderContent() throws Exception { OrgParserSettings settings = new OrgParserSettings();