package eu.svjatoslav.sixth.core.document;
+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.PRESERVE;
+import static eu.svjatoslav.sixth.core.document.Helper.*;
+import static eu.svjatoslav.sixth.core.document.text.FormattedText.fromOrg;
+
public class Document {
+ public final Heading rootHeading = new Heading( null , 0, null);
+ private Heading currentHeading = rootHeading;
+
+ public Heading createHeading(FormattedText name, int targetLevel){
+ if (currentHeading.level == (targetLevel - 1)){
+ Heading newHeading = new Heading(name, targetLevel, currentHeading);
+ currentHeading.addChild(newHeading);
+ currentHeading = newHeading;
+ return newHeading;
+ }
+
+ if (currentHeading.level > (targetLevel - 1)){
+ currentHeading = currentHeading.parent;
+ return createHeading(name, targetLevel);
+ }
+
+ Heading missingIntermediate = new Heading(fromOrg("<noname>"), currentHeading.level + 1, currentHeading);
+ currentHeading.addChild(missingIntermediate);
+ currentHeading = missingIntermediate;
+ return createHeading(name, targetLevel);
+ }
+
+ public Heading getCurrentHeading(){
+ return currentHeading;
+ }
+
+ private void parseHeading(TokenizerMatch token) throws InvalidSyntaxException {
+ String[] headingSections = token.getRegExpGroups();
+ int level = headingSections[0].length();
+ String title = headingSections[1];
+ createHeading(fromOrg(title), level);
+ }
+
+ public void parse(String fileContentsAsString) throws InvalidSyntaxException {
+ final Tokenizer tokenizer = new Tokenizer(fileContentsAsString);
+
+ // Org heading:
+ // "*** Example Heading 1234"
+ 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);
+
+ // " * my list title"
+ tokenizer.addTerminator(PRESERVE, "([ \\t]+)(\\*)[ \\t]+(.*)?\\r?\\n", TG_LIST);
+
+ // TODO: add numbered list
+
+ // DocumentProperty:
+ // "#+OPTIONS: H:20 num:20"
+ 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
+
+
+ // normal text
+ tokenizer.addTerminator(PRESERVE,".*\\r?\\n", TG_NORMAL_TEXT);
+
+ while (tokenizer.hasMoreContent()) {
+ final TokenizerMatch tm = tokenizer.getNextToken();
+
+ if (tm.isGroup(TG_HEADING)){
+ parseHeading(tm);
+ continue;
+ }
+
+ currentHeading.parse(tm);
+ }
+
+ }
}