package eu.svjatoslav.sixth.core.document;
-import eu.svjatoslav.commons.string.tokenizer.InvalidSyntaxException;
+import eu.svjatoslav.commons.string.String2;
import eu.svjatoslav.commons.string.tokenizer.Tokenizer;
import eu.svjatoslav.commons.string.tokenizer.TokenizerMatch;
+import eu.svjatoslav.sixth.core.document.content.ListElement;
import eu.svjatoslav.sixth.core.document.text.FormattedText;
import java.util.ArrayList;
import java.util.List;
-import static eu.svjatoslav.sixth.core.document.Helper.TG_DOCUMENT_PROPERTY;
import static eu.svjatoslav.sixth.core.document.Helper.TG_LIST;
-import static eu.svjatoslav.sixth.core.document.text.FormattedText.fromOrg;
public class Heading {
public final FormattedText name;
public final Heading parent;
private final List<Heading> children = new ArrayList<>();
- public final ListElement rootListElement = new ListElement(null, 0, null);
+ public final ListElement rootListElement = new ListElement(null, -2, null, "");
private ListElement currentListElement = rootListElement;
public Heading(FormattedText name, int level, Heading parent){
if (level > 0) sb.append(enlistTitleInMD());
- // sb.append(unparsedContent);
-
+ rootListElement.toMD(sb, -2);
children.stream().map(Heading::toMD).forEach(sb::append);
}
private String enlistTitleInMD() {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < level; i++)
- sb.append("#");
+ String2 s = new String2();
+ s.append("#", level).append(" ").append(name.toMD(0)).append("\n");
+ return s.toString();
+ }
- sb.append(" ").append(name.compileMd()).append("\n");
- return sb.toString();
+ public ListElement getCurrentHeading(){
+ return currentListElement;
}
- public ListElement createListElement(FormattedText name, int targetLevel){
- if (currentListElement.level == (targetLevel - 1)){
- ListElement newListElement = new ListElement(name, targetLevel, currentListElement);
- currentListElement.addChild(newListElement);
- currentListElement = newListElement;
- return newListElement;
+ public void parse(TokenizerMatch tm){
+
+ if (tm.isGroup(TG_LIST)){
+ parseList(tm);
+ return;
}
- if (currentListElement.level > (targetLevel - 1)){
- currentListElement = currentListElement.parent;
- return createListElement(name, targetLevel);
+ currentListElement.parse(tm);
+ }
+
+ private void parseList(TokenizerMatch tm) {
+ String[] listSections = tm.getRegExpGroups();
+ int indent = listSections[0].length();
+ String type = listSections[1];
+ FormattedText title = FormattedText.fromOrg(parseFullListTitle(getPartialTitle(listSections), tm.getTokenizer(), indent));
+
+ if (indent > currentListElement.indent){
+ // list dept increases
+ ListElement newElement = new ListElement(title, indent, currentListElement, type);
+ currentListElement.addContent(newElement);
+ currentListElement = newElement;
+ return;
}
- try {
- ListElement missingIntermediate = new ListElement(
- fromOrg("<noname>"), currentListElement.level + 1, currentListElement);
- currentListElement.addChild(missingIntermediate);
- currentListElement = missingIntermediate;
- return createListElement(name, targetLevel);
- } catch (InvalidSyntaxException e) {
- throw new IllegalStateException("impossible situation");
+ if (indent == currentListElement.indent){
+ // list depth is the same
+ ListElement newElement = new ListElement(title, indent, currentListElement.parent, type);
+ currentListElement.parent.addContent(newElement);
+ currentListElement = newElement;
+ return;
+ }
+
+ // list dept decreases
+ while (true){
+ if (currentListElement.parent.indent <= indent){
+ if (currentListElement.parent.indent < 0){
+ // reached first depth level, cannot go any deeper.
+ // This special situation arisesbb only when lint indents are not properly aligned.
+ // That is, document structure is incorrect.
+ ListElement newElement = new ListElement(title, indent, currentListElement.parent, type);
+ currentListElement.parent.addContent(newElement);
+ currentListElement = newElement;
+ return;
+ }
+
+ ListElement newElement = new ListElement(title, indent, currentListElement.parent.parent, type);
+ currentListElement.parent.parent.addContent(newElement);
+ currentListElement = newElement;
+ return;
+ }
+ currentListElement = currentListElement.parent;
}
- }
- public ListElement getCurrentHeading(){
- return currentListElement;
}
- public void parse(Tokenizer tokenizer){
- while (tokenizer.hasMoreContent()) {
- final TokenizerMatch tm = tokenizer.getNextToken();
+ private String getPartialTitle(String[] listSections) {
+ return listSections.length > 2 ? listSections[2] : "";
+ }
- if (tm.isGroup(TG_LIST)){
- System.out.println("LIST!: " + tm.token);
- continue;
- }
+ private String parseFullListTitle(String partialTitle, Tokenizer tokenizer, int listIndent){
+ StringBuilder sb = new StringBuilder();
+ sb.append(partialTitle);
- if (tm.isGroup(TG_DOCUMENT_PROPERTY)){
-// System.out.println("DOCUMENT PROPERTY!!!: " + tm.token);
- continue;
- }
+ while (tokenizer.hasMoreContent()){
+ final TokenizerMatch tm = tokenizer.getNextToken();
- if (tm.isGroup(null)){
- System.out.println("unhandled \"" + tm.token + "\"");
+ if (isContentContinuation(tm, listIndent, Helper.TG_NORMAL_TEXT)){
+ String titleContinuation = tm.token.substring(listIndent).trim();
+ sb.append("\n").append(titleContinuation);
continue;
}
tokenizer.unreadToken();
break;
}
+
+ return sb.toString();
}
+
+ public static boolean isContentContinuation(TokenizerMatch tm, int requiredIndent, String requiredGroup) {
+ if (tm.token.length() <= requiredIndent) return false;
+
+ return tm.isGroup(requiredGroup) && tm.token.substring(0, requiredIndent +1).trim().length() == 0;
+ }
+
}