Separate multiline code block language from remaining parameters
[sixth.git] / src / main / java / eu / svjatoslav / sixth / core / document / Document.java
index 262bee3..c61d613 100644 (file)
@@ -1,12 +1,10 @@
 package eu.svjatoslav.sixth.core.document;
 
-import eu.svjatoslav.commons.string.String2;
 import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
 import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
 import eu.svjatoslav.commons.string.tokenizer.TokenizerMatch;
 import eu.svjatoslav.sixth.core.document.text.FormattedText;
 
-import static eu.svjatoslav.commons.string.tokenizer.Terminator.TerminationStrategy.DROP;
 import static eu.svjatoslav.commons.string.tokenizer.Terminator.TerminationStrategy.PRESERVE;
 import static eu.svjatoslav.sixth.core.document.Helper.*;
 import static eu.svjatoslav.sixth.core.document.text.FormattedText.fromOrg;
@@ -28,14 +26,10 @@ public class Document {
             return createHeading(name, targetLevel);
         }
 
-        try {
-            Heading missingIntermediate = new Heading(fromOrg("<noname>"), currentHeading.level + 1, currentHeading);
-            currentHeading.addChild(missingIntermediate);
-            currentHeading = missingIntermediate;
-            return createHeading(name, targetLevel);
-        } catch (InvalidSyntaxException e) {
-            throw new IllegalStateException("impossible situation");
-        }
+        Heading missingIntermediate = new Heading(fromOrg("<noname>"), currentHeading.level + 1, currentHeading);
+        currentHeading.addChild(missingIntermediate);
+        currentHeading = missingIntermediate;
+        return createHeading(name, targetLevel);
     }
 
     public Heading getCurrentHeading(){
@@ -43,10 +37,7 @@ public class Document {
     }
 
     private void parseHeading(TokenizerMatch token) throws InvalidSyntaxException {
-        // expected sample heading:
-        // ***** test heading
-
-        String[] headingSections = String2.getGroups(token.token, "(\\*+)[ \\t](.*)\\r?\\n");
+        String[] headingSections = token.getRegExpGroups();
         int level = headingSections[0].length();
         String title = headingSections[1];
         createHeading(fromOrg(title), level);
@@ -57,23 +48,52 @@ public class Document {
 
         // Org heading:
         // "*** Example Heading 1234"
-        tokenizer.addTerminator(PRESERVE, "\\*+[ \\t].*\\r?\\n", TG_HEADING);
+        tokenizer.addTerminator(PRESERVE, "(\\*+)[ \\t](.*)\\r?\\n", TG_HEADING);
 
         // Org list. Examples:
         // "   + my list title"
         // "   - my list title"
-        tokenizer.addTerminator(PRESERVE, "[ \\t]*(\\+|-)([ \\t].*)?\\r?\\n", TG_LIST);
+        tokenizer.addTerminator(PRESERVE, "([ \\t]*)(\\+|-)[ \\t]+(.*)?\\r?\\n", TG_LIST);
 
         // "   * my list title"
-        tokenizer.addTerminator(PRESERVE, "[ \\t]+\\*([ \\t].*)?\\r?\\n", TG_LIST);
+        tokenizer.addTerminator(PRESERVE, "([ \\t]+)(\\*)[ \\t]+(.*)?\\r?\\n", TG_LIST);
+
+        // TODO: add numbered list
 
         // DocumentProperty:
         // "#+OPTIONS: H:20 num:20"
-        tokenizer.addTerminator(PRESERVE, "#\\+.+:.*\\r?\\n", TG_DOCUMENT_PROPERTY);
+        tokenizer.addTerminator(PRESERVE, "#\\+([^\\s]+):(.*)\\r?\\n", TG_DOCUMENT_PROPERTY);
+
+        // Drawer property:
+        //  " :ID:       533734b9-0456-4448-9830-a43646345615"
+        tokenizer.addTerminator(PRESERVE, "([ \\t]*):([^\\s]+):(.*)\\r?\\n", TG_DRAWER_PROPERTY);
+
+
+        // multiline code block
+        tokenizer.addTerminator(PRESERVE,
+                "([ \\t]*)#\\+BEGIN_SRC" +  // source begin identifier
+                        "(([ \\t]+)(.*))?(\\r?\\n)" + // source block parameters
+                        "((?:.|\\n|\\r)*?)" + // source content
+                        "(\\r?\\n)([ \\t]*)#\\+END_SRC(.*)\\r?\\n" // source end identifier
+                , TG_MULTILINE_CODE);
+
+        // verse
+        tokenizer.addTerminator(PRESERVE,
+                "([ \\t]*)#\\+BEGIN_VERSE" + // verse begin identifier
+                        "(([ \\t]+)(.*))?(\\r?\\n)" + // verse block parameters
+                        "((?:.|\\n|\\r)*?)" + // verse
+                        "(\\r?\\n)([ \\t]*)#\\+END_VERSE(.*)\\r?\\n" // verse end identifier
+                , TG_VERSE);
+
+
+        // TODO: add support for export blocks:
+        //        #+begin_export latex
+        //  \clearpage
+        //#+end_export
 
-        // newline
-        tokenizer.addTerminator(DROP,"\\r?\\n", TG_NEWLINE);
 
+        // normal text
+        tokenizer.addTerminator(PRESERVE,".*\\r?\\n", TG_NORMAL_TEXT);
 
         while (tokenizer.hasMoreContent()) {
             final TokenizerMatch tm = tokenizer.getNextToken();
@@ -83,8 +103,7 @@ public class Document {
                 continue;
             }
 
-            tokenizer.unreadToken();
-            currentHeading.parse(tokenizer);
+            currentHeading.parse(tm);
         }
 
     }