From 5779703575e0b13a5cb31f481c45085549833233 Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@gmail.com>
Date: Tue, 12 Mar 2019 23:07:10 +0100
Subject: [PATCH] twine tags fully work

---
 SanityCheck.jar                               | Bin 15389 -> 20708 bytes
 devTools/javaSanityCheck/htmlTags             |   6 +-
 .../src/DisallowedTagException.java           |   8 +
 devTools/javaSanityCheck/src/Main.java        | 110 ++++---
 devTools/javaSanityCheck/src/SyntaxError.java |   2 +-
 .../javaSanityCheck/src/{tag => }/Tag.java    |   6 +-
 .../javaSanityCheck/src/TagSearchTree.java    |  42 ++-
 .../src/element/AngleBracketElement.java      | 275 ++++++++++++++----
 .../src/element/CommentElement.java           |  66 +++++
 .../javaSanityCheck/src/element/Element.java  |   9 +-
 .../src/element/KnownElement.java             |  31 ++
 .../src/element/KnownHtmlElement.java         |  40 +--
 .../src/element/KnownLogicElement.java        | 117 ++++++++
 .../src/element/KnownTwineElement.java        |  41 +++
 devTools/javaSanityCheck/src/tag/HtmlTag.java |   7 -
 devTools/javaSanityCheck/twineTags            | 114 +-------
 16 files changed, 616 insertions(+), 258 deletions(-)
 create mode 100644 devTools/javaSanityCheck/src/DisallowedTagException.java
 rename devTools/javaSanityCheck/src/{tag => }/Tag.java (52%)
 create mode 100644 devTools/javaSanityCheck/src/element/CommentElement.java
 create mode 100644 devTools/javaSanityCheck/src/element/KnownElement.java
 create mode 100644 devTools/javaSanityCheck/src/element/KnownLogicElement.java
 create mode 100644 devTools/javaSanityCheck/src/element/KnownTwineElement.java
 delete mode 100644 devTools/javaSanityCheck/src/tag/HtmlTag.java

diff --git a/SanityCheck.jar b/SanityCheck.jar
index ae0827bf18a9d723f76089c40656eceb4da08e8c..bebdf1da3e6277f966e8fff78ea96d884fe27b0b 100644
GIT binary patch
delta 16212
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

delta 11157
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

diff --git a/devTools/javaSanityCheck/htmlTags b/devTools/javaSanityCheck/htmlTags
index 608a30a5ff6..751b084ff58 100644
--- a/devTools/javaSanityCheck/htmlTags
+++ b/devTools/javaSanityCheck/htmlTags
@@ -1,5 +1,5 @@
 #Allowed HTML tags
-#Effectively everything that is allowed in one of these statements like this:
+#Effectively everything that is allowed in a these statements like this:
 #<tag> or <tag ???>
 #when ;1 is specified it expects a matching closing tag like this: </tag>
 #Do not add Twine Tags here.
@@ -25,11 +25,11 @@ h1;1
 h2;1
 h3;1
 h4;1
-hr;1
+hr;0
 html;1
 i;1
 img;1
-input;1
+input;0
 li;1
 option;1
 script;1
diff --git a/devTools/javaSanityCheck/src/DisallowedTagException.java b/devTools/javaSanityCheck/src/DisallowedTagException.java
new file mode 100644
index 00000000000..f4cc75e736b
--- /dev/null
+++ b/devTools/javaSanityCheck/src/DisallowedTagException.java
@@ -0,0 +1,8 @@
+package org.arkerthan.sanityCheck;
+
+public class DisallowedTagException extends RuntimeException {
+
+    public DisallowedTagException(String tag) {
+        super(tag);
+    }
+}
diff --git a/devTools/javaSanityCheck/src/Main.java b/devTools/javaSanityCheck/src/Main.java
index 6a7aee137ca..eea3a4ff611 100644
--- a/devTools/javaSanityCheck/src/Main.java
+++ b/devTools/javaSanityCheck/src/Main.java
@@ -1,11 +1,9 @@
 package org.arkerthan.sanityCheck;
 
 import org.arkerthan.sanityCheck.element.AngleBracketElement;
-import org.arkerthan.sanityCheck.element.AtElement;
+import org.arkerthan.sanityCheck.element.CommentElement;
 import org.arkerthan.sanityCheck.element.Element;
-import org.arkerthan.sanityCheck.element.KnownHtmlElement;
-import org.arkerthan.sanityCheck.tag.HtmlTag;
-import org.arkerthan.sanityCheck.tag.Tag;
+import org.arkerthan.sanityCheck.element.KnownElement;
 
 import java.io.*;
 import java.nio.charset.Charset;
@@ -16,7 +14,7 @@ import java.util.*;
 
 public class Main {
 
-    public static TagSearchTree<HtmlTag> htmlTags;
+    public static TagSearchTree<Tag> htmlTags, twineTags;
     private static String currentFile;
     private static int currentLine, currentPosition;
     private static Stack<Element> stack;
@@ -27,6 +25,7 @@ public class Main {
         //setup
         setupExclude();
         setupHtmlTags();
+        setupTwineTags();
         Path workingDir = Paths.get("").toAbsolutePath();
 
         //actual sanityCheck
@@ -42,7 +41,7 @@ public class Main {
 
     /**
      * Goes through the whole directory including subdirectories and runs
-     * sanitycheck() on all .tw files
+     * sanityCheck() on all .tw files
      *
      * @param dir to be checked
      */
@@ -61,7 +60,9 @@ public class Main {
                 }
             }
         } catch (NullPointerException e) {
-            System.err.println("Couldn't find directory " + dir.getPath());
+            e.printStackTrace();
+            System.err.println("Couldn't find directory " + currentFile);
+            System.exit(-1);
         }
     }
 
@@ -96,23 +97,23 @@ public class Main {
     }
 
     /**
-     * sets up the alphabetical search tree for fast access later
+     * sets up the alphabetical search tree for fast access of HTML tags later
      */
     private static void setupHtmlTags() {
         //load HTML tags into a list
-        List<Tag> htmlTagsList = new LinkedList<>();
+        List<Tag> TagsList = new LinkedList<>();
         try {
 
             Files.lines(new File("devTools/javaSanityCheck/htmlTags").toPath()).map(String::trim)
                     .filter(s -> !s.startsWith("#"))
-                    .forEach(s -> htmlTagsList.add(parseTag(s)));
+                    .forEach(s -> TagsList.add(parseTag(s)));
         } catch (IOException e) {
             System.err.println("Couldn't read devTools/javaSanityCheck/htmlTags");
         }
 
         //turn List into alphabetical search tree
         try {
-            htmlTags = new TagSearchTree(htmlTagsList);
+            htmlTags = new TagSearchTree(TagsList);
         } catch (ArrayIndexOutOfBoundsException e) {
             System.err.println("Illegal Character in devTools/javaSanityCheck/htmlTags");
             System.exit(-1);
@@ -120,18 +121,42 @@ public class Main {
     }
 
     /**
-     * Turns a string into a HtmlTag
+     * sets up the alphabetical search tree for fast access of twine tags later
+     */
+    private static void setupTwineTags() {
+        //load twine tags into a list
+        List<Tag> TagsList = new LinkedList<>();
+        try {
+
+            Files.lines(new File("devTools/javaSanityCheck/twineTags").toPath()).map(String::trim)
+                    .filter(s -> !s.startsWith("#"))
+                    .forEach(s -> TagsList.add(parseTag(s)));
+        } catch (IOException e) {
+            System.err.println("Couldn't read devTools/javaSanityCheck/twineTags");
+        }
+
+        //turn List into alphabetical search tree
+        try {
+            twineTags = new TagSearchTree(TagsList);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.err.println("Illegal Character in devTools/javaSanityCheck/twineTags");
+            System.exit(-1);
+        }
+    }
+
+    /**
+     * Turns a string into a Tag
      * ";1" at the end of the String indicates that the tag needs to be closed later
      *
      * @param s tag as String
-     * @return tag as HtmlTag
+     * @return tag as Tag
      */
-    private static HtmlTag parseTag(String s) {
+    private static Tag parseTag(String s) {
         String[] st = s.split(";");
         if (st.length > 1 && st[1].equals("1")) {
-            return new HtmlTag(st[0], false);
+            return new Tag(st[0], false);
         }
-        return new HtmlTag(st[0], true);
+        return new Tag(st[0], true);
     }
 
     /**
@@ -225,45 +250,64 @@ public class Main {
                 if (change == 2) {
                     //remove the topmost element from stack since it is complete
                     stack.pop();
+                    return;
                 }
                 //3 means the Element is complete and part of a two tag system
                 if (change == 3) {
                     //remove the topmost element from stack since it is complete
-                    KnownHtmlElement k = stack.pop().getKnownElement();
-                    if (k.isOpening()) {
+                    KnownElement k = stack.pop().getKnownElement();
+                    /*if (k.isOpening()) {
                         stack.push(k);
-                    } else if (stack.empty()) {
-                        addError(new SyntaxError("Closed HTML tag \"" + k.getStatement() + "\" without having any open tags.", -1));
-                    } else if (stack.peek() instanceof KnownHtmlElement) {
-                        KnownHtmlElement kFirst = (KnownHtmlElement) stack.peek();
-                        if (!kFirst.isMatchingElement(k)) {
-                            addError(new SyntaxError("Opening HTML tag \"" + kFirst.getStatement() +
-                                    "\" does not match closing tag \"" + k.getStatement() + "\".", -1));
+                    } else */
+                    if (k.isClosing()) {
+                        if (stack.empty()) {
+                            addError(new SyntaxError("Closed tag " + k.getShortDescription() + " without having any open tags.", -2));
+                        } else if (stack.peek() instanceof KnownElement) {
+                            KnownElement kFirst = (KnownElement) stack.pop();
+                            if (!kFirst.isMatchingElement(k)) {
+                                addError(new SyntaxError("Opening tag " + kFirst.getShortDescription() +
+                                        " does not match closing tag " + k.getShortDescription() + ".", -2));
+                            }
+                            //stack.pop();
+                        } else {
+                            addError(new SyntaxError("Closing tag " + k.getShortDescription() + " inside " +
+                                    "another tag: " + stack.peek().getShortDescription(), -2, true));
                         }
-                        stack.pop();
-                    } else {
-                        addError(new SyntaxError("Closing HTML tag \"" + k.getStatement() + "\" inside " +
-                                "another tag: " + stack.peek().getShortDescription(), -1, true));
                     }
+                    if (k.isOpening()) {
+                        stack.push(k);
+                    }
+                    return;
+                }
+                if (change == 4) {
+                    stack.pop();
+                } else {
+                    return;
                 }
-                return;
             }
         }
 
 
         //innermost element was uninterested, trying to find matching element
         switch (c) {
-            case '@':
-                stack.push(new AtElement(currentLine, currentPosition));
-                break;
+            //case '@':
+            //  stack.push(new AtElement(currentLine, currentPosition));
+            //break;
             case '<':
                 stack.push(new AngleBracketElement(currentLine, currentPosition));
                 break;
+            //case '>':
+            //addError(new SyntaxError("Dangling \">\", current innermost: " + (stack.empty() ? "null" : stack.peek().getShortDescription()), -2));
+            //break;
+            case '/':
+                stack.push(new CommentElement(currentLine, currentPosition));
+                break;
         }
     }
 
     /**
      * add an error to the error list
+     *
      * @param e new error
      */
     private static void addError(SyntaxError e) {
diff --git a/devTools/javaSanityCheck/src/SyntaxError.java b/devTools/javaSanityCheck/src/SyntaxError.java
index 90d9db7333c..150f2bd449b 100644
--- a/devTools/javaSanityCheck/src/SyntaxError.java
+++ b/devTools/javaSanityCheck/src/SyntaxError.java
@@ -4,7 +4,7 @@ public class SyntaxError extends Exception {
     private String file;
     private int line, position;
     private String description;
-    private int change; //see Element for values; -1 means not thrown
+    private int change; //see Element for values; -2 means not thrown
     private boolean warning = false;
 
     public SyntaxError(String description, int change) {
diff --git a/devTools/javaSanityCheck/src/tag/Tag.java b/devTools/javaSanityCheck/src/Tag.java
similarity index 52%
rename from devTools/javaSanityCheck/src/tag/Tag.java
rename to devTools/javaSanityCheck/src/Tag.java
index 386292b48eb..8a13ee4f7a1 100644
--- a/devTools/javaSanityCheck/src/tag/Tag.java
+++ b/devTools/javaSanityCheck/src/Tag.java
@@ -1,10 +1,10 @@
-package org.arkerthan.sanityCheck.tag;
+package org.arkerthan.sanityCheck;
 
-public abstract class Tag {
+public class Tag {
     public final String tag;
     public final boolean single;
 
-    protected Tag(String tag, boolean single) {
+    public Tag(String tag, boolean single) {
         this.tag = tag;
         this.single = single;
     }
diff --git a/devTools/javaSanityCheck/src/TagSearchTree.java b/devTools/javaSanityCheck/src/TagSearchTree.java
index 567f33f35d7..dde49df879a 100644
--- a/devTools/javaSanityCheck/src/TagSearchTree.java
+++ b/devTools/javaSanityCheck/src/TagSearchTree.java
@@ -1,32 +1,52 @@
 package org.arkerthan.sanityCheck;
 
-import org.arkerthan.sanityCheck.tag.Tag;
-
 import java.util.List;
 
+/**
+ * Tag SearchTree stores Tags in an alphabetical search tree.
+ * Once created the search tree can't be changed anymore.
+ *
+ * @param <E> Tag class to be stored
+ */
 public class TagSearchTree<E extends Tag> {
     private static final int SIZE = 128;
+    private final TagSearchTree<E>[] branches;
     private E element = null;
-    private TagSearchTree<E>[] branches;
     private String path;
 
+    /**
+     * creates a new empty TagSearchTree
+     */
     private TagSearchTree() {
         branches = new TagSearchTree[SIZE];
     }
 
+    /**
+     * Creates a new filled TagSearchTree
+     *
+     * @param list Tags to be inserted
+     */
     public TagSearchTree(List<E> list) {
         this();
-        for (E e :
-                list) {
+        for (E e : list) {
             this.add(e, 0);
         }
     }
 
+    /**
+     * adds a new Tag to the TagSearchTree
+     *
+     * @param e     Tag to be stored
+     * @param index index of relevant char for adding in tag
+     */
     private void add(E e, int index) {
-        path = e.tag.substring(0,index);
+        //set the path to here
+        path = e.tag.substring(0, index);
+        //checks if tag has to be stored here or further down
         if (e.tag.length() == index) {
             element = e;
         } else {
+            //store tag in correct branch
             char c = e.tag.charAt(index);
             if (branches[c] == null) {
                 branches[c] = new TagSearchTree<>();
@@ -35,15 +55,25 @@ public class TagSearchTree<E extends Tag> {
         }
     }
 
+    /**
+     * @param c character of branch needed
+     * @return branch or null if branch doesn't exist
+     */
     public TagSearchTree<E> getBranch(char c) {
         if (c >= SIZE) return null;
         return branches[c];
     }
 
+    /**
+     * @return stored Tag, null if empty
+     */
     public E getElement() {
         return element;
     }
 
+    /**
+     * @return path inside full tree to get to this Branch
+     */
     public String getPath() {
         return path;
     }
diff --git a/devTools/javaSanityCheck/src/element/AngleBracketElement.java b/devTools/javaSanityCheck/src/element/AngleBracketElement.java
index 35877dec434..e4819ba37ea 100644
--- a/devTools/javaSanityCheck/src/element/AngleBracketElement.java
+++ b/devTools/javaSanityCheck/src/element/AngleBracketElement.java
@@ -1,28 +1,39 @@
 package org.arkerthan.sanityCheck.element;
 
-import org.arkerthan.sanityCheck.Main;
-import org.arkerthan.sanityCheck.SyntaxError;
-import org.arkerthan.sanityCheck.TagSearchTree;
-import org.arkerthan.sanityCheck.UnknownStateException;
-import org.arkerthan.sanityCheck.tag.HtmlTag;
+import org.arkerthan.sanityCheck.*;
+
+import java.util.Arrays;
+import java.util.List;
 
 public class AngleBracketElement extends Element {
+    private static final List<String> logicTags = Arrays.asList("if", "elseif", "else", "switch", "case", "default");
     private int state = 0;
     /*
-    -1 - </
      0 - initial: <
+     TWINE
      1 - <<
-     2 - <<abc
-     3 - <<abc>
-
-     4 - trying to complete HTML tag: <tag ???>
-    -4 - trying to complete HTML tag: </tag>
-     5 - waiting for >
+    -1 - <</
+     2 - trying to complete twine tag: <<tag ???>>
+    -2 - trying to complete twine tag: <</tag>>
+     3 - waiting for >>
+    -3 - expecting > from 3
+     4 - waiting for >> with KnownElement
+    -4 - expecting > from 4
+     5 - expecting >>
     -5 - expecting >
-     6 - waiting for > with KnownHtmlElement
+     6 - expecting > with KnownElement opening; comparison?
+    -6 - expecting > with KnownElement closing
+
+     HTML
+    -9 - </
+    10 - trying to complete HTML tag: <tag ???>
+   -10 - trying to complete HTML tag: </tag>
+    11 - waiting for >
+   -11 - expecting >
+    12 - waiting for > with KnownElement
      */
 
-    private TagSearchTree<HtmlTag> htmlTree;
+    private TagSearchTree<Tag> tree;
 
     public AngleBracketElement(int line, int pos) {
         super(line, pos);
@@ -39,7 +50,7 @@ public class AngleBracketElement extends Element {
                     case '>':
                         throw new SyntaxError("Empty Statement?", 2);
                     case '/':
-                        state = -1;
+                        state = -9;
                         return 1;
                     case ' ':// assume comparison
                     case '=':// "
@@ -48,63 +59,118 @@ public class AngleBracketElement extends Element {
                         return 2;
                     default:
                         try {
-                            state = 4;
-                            htmlTree = Main.htmlTags;
+                            state = 10;
+                            tree = Main.htmlTags;
                             return handleOpeningHTML(c);
                         } catch (SyntaxError e) {
                             state = 1;
                             throw new SyntaxError("Opening \"<\" missing, found " + c + " [debug:initialCase]", 1);
                         }
                 }
-            case -1:
-                if (c == '>') {
-                    throw new SyntaxError("Empty Statement?", 2, true);
-                }
-                state = -4;
-                htmlTree = Main.htmlTags;
-                return handleClosingHTML(c);
             case 1:
                 if (c == '<') {
                     throw new SyntaxError("Too many \"<\".", 1);
                 } else if (c == '>') {
                     state = 3;
                     throw new SyntaxError("Empty Statement?", 1);
-                } else {
-                    state = 2;
+                } else if (c == '/') {
+                    state = -1;
                     return 1;
                 }
+                state = 2;
+                tree = Main.twineTags;
+                return handleOpeningTwine(c);
+            case -1:
+                if (c == '>') {
+                    throw new SyntaxError("Empty Statement?", 2, true);
+                }
+                state = -2;
+                tree = Main.twineTags;
+                return handleClosingTwine(c);
+
             case 2:
-                //TODO finding special Twine statements: IF, ELSE...
+                return handleOpeningTwine(c);
+            case -2:
+                return handleClosingTwine(c);
+            case 3:
                 if (c == '>') {
-                    state = 3;
+                    state = -3;
                     return 1;
                 }
                 break;
-            case 3:
+            case -3:
                 if (c == '>') {
                     return 2;
                 } else if (c == ' ' || c == '=') { // assuming comparison
-                    state = 2;
+                    state = 3;
+                    return 1;
                 } else {
-                    throw new SyntaxError("Closing \">\" missing [1]", 2);
+                    throw new SyntaxError("Closing \">\" missing, opened [" + line + ":" + pos + "]", 2);
+                }
+            case 4:
+                if (c == '>') {
+                    state = -4;
+                    return 1;
                 }
                 break;
+            case -4:
+                if (c == '>') {
+                    return 3;
+                } else if (c == ' ' || c == '=') { // assuming comparison
+                    state = 4;
+                    return 1;
+                } else {
+                    throw new SyntaxError("Closing \">\" missing, opened [" + line + ":" + pos + "]", 2);
+                }
+            case 5:
+                if (c == '>') {
+                    state = -5;
+                    return 1;
+                } else {
+                    throw new SyntaxError("Closing \">\" missing, opened [" + line + ":" + pos + "]", 2);
+                }
+            case -5:
+                if (c == '>') {
+                    return 2;
+                }
+                throw new SyntaxError("Closing \">\" missing, opened [" + line + ":" + pos + "]", 2);
+            case 6:
+                if (c == '>') {
+                    return 3;
+                } else if (c == ' ' || c == '=') {
+                    state = 3;
+                    return 1;
+                } else {
+                    throw new SyntaxError("Closing \">\" missing, opened [" + line + ":" + pos + "]", 3);
+                }
+            case -6:
+                if (c == '>') {
+                    return 3;
+                }
+                throw new SyntaxError("Closing \">\" missing, opened [" + line + ":" + pos + "]", 3);
 
-            case 4:
+            case -9:
+                if (c == '>') {
+                    throw new SyntaxError("Empty Statement?", 2, true);
+                }
+                state = -10;
+                tree = Main.htmlTags;
+                return handleClosingHTML(c);
+            case 10:
                 return handleOpeningHTML(c);
-            case -4:
+            case -10:
                 return handleClosingHTML(c);
-            case 5:
+            case 11:
                 if (c == '>')
                     return 2;
                 if (c == '@') //@ inside HTML tags is allowed
                     return 1;
                 break;
-            case -5:
+            case -11:
                 if (c == '>')
                     return 2;
                 throw new SyntaxError("Closing \">\" missing [2]", 2);
-            case 6:
+            case 12:
                 if (c == '>')
                     return 3;
                 if (c == '@') //@ inside HTML tags is allowed
@@ -118,31 +184,31 @@ public class AngleBracketElement extends Element {
 
     private int handleOpeningHTML(char c) throws SyntaxError {
         if (c == ' ') {
-            state = 5;
-            if (htmlTree.getElement() == null) {
+            state = 11;
+            if (tree.getElement() == null) {
                 throw new SyntaxError("Unknown HTML tag", 1);
             }
-            if (!htmlTree.getElement().single) {
-                k = new KnownHtmlElement(line, pos, true, htmlTree.getElement().tag);
-                state = 6;
+            if (!tree.getElement().single) {
+                k = new KnownHtmlElement(line, pos, true, tree.getElement().tag);
+                state = 12;
                 return 1;
             }
             return 1;
         }
         if (c == '>') {
-            if (htmlTree.getElement() == null) {
+            if (tree.getElement() == null) {
                 throw new SyntaxError("Unknown HTML tag", 2);
             }
-            if (!htmlTree.getElement().single) {
-                k = new KnownHtmlElement(line, pos, true, htmlTree.getElement().tag);
+            if (!tree.getElement().single) {
+                k = new KnownHtmlElement(line, pos, true, tree.getElement().tag);
                 return 3;
             }
             return 2;
         }
 
-        htmlTree = htmlTree.getBranch(c);
-        if (htmlTree == null) {
-            state = 5;
+        tree = tree.getBranch(c);
+        if (tree == null) {
+            state = 11;
             throw new SyntaxError("Unknown HTML tag or closing \">\" missing, found " + c, 1);
         }
 
@@ -151,29 +217,104 @@ public class AngleBracketElement extends Element {
 
     private int handleClosingHTML(char c) throws SyntaxError {
         if (c == '>') {
-            if (htmlTree.getElement() == null) {
+            if (tree.getElement() == null) {
                 throw new SyntaxError("Unknown HTML tag", 2);
             }
-            if (htmlTree.getElement().single) {
-                throw new SyntaxError("Single HTML tag used as closing Tag: " + htmlTree.getElement().tag, 2);
+            if (tree.getElement().single) {
+                throw new SyntaxError("Single HTML tag used as closing Tag: " + tree.getElement().tag, 2);
             }
-            k = new KnownHtmlElement(line, pos, false, htmlTree.getElement().tag);
+            k = new KnownHtmlElement(line, pos, false, tree.getElement().tag);
             return 3;
         }
 
-        htmlTree = htmlTree.getBranch(c);
-        if (htmlTree == null) {
-            state = -5;
+        tree = tree.getBranch(c);
+        if (tree == null) {
+            state = -11;
             throw new SyntaxError("Unknown HTML tag or closing \">\" missing, found " + c, 1);
         }
 
         return 1;
     }
 
+
+    private int handleOpeningTwine(char c) throws SyntaxError {
+        if (c == ' ') {
+            state = 3;
+            if (tree.getElement() == null) {
+                //assuming not listed means widget until better solution
+                return 1;
+                //throw new SyntaxError("Unknown Twine tag or closing \">>\" missing, found " + tree.getPath(), 1);
+            }
+            if (!tree.getElement().single) {
+                if (logicTags.contains(tree.getElement().tag)) {
+                    k = new KnownLogicElement(line, pos, tree.getElement().tag, false);
+                } else {
+                    k = new KnownTwineElement(line, pos, true, tree.getElement().tag);
+                }
+                state = 4;
+                return 1;
+            }
+            return 1;
+        }
+        if (c == '>') {
+            state = -5;
+            if (tree.getElement() == null) {
+                //assuming not listed means widget until better solution
+                //throw new SyntaxError("Unknown Twine tag or closing \">>\" missing, found " + tree.getPath(), 1);
+                return 1;
+            }
+            if (!tree.getElement().single) {
+                if (logicTags.contains(tree.getElement().tag)) {
+                    k = new KnownLogicElement(line, pos, tree.getElement().tag, false);
+                } else {
+                    k = new KnownTwineElement(line, pos, true, tree.getElement().tag);
+                }
+                state = 6;
+                return 1;
+            }
+            return 2;
+        }
+
+        tree = tree.getBranch(c);
+        if (tree == null) {
+            //assuming not listed means widget until better solution
+            state = 3;
+            //throw new SyntaxError("Unknown Twine tag or closing \">>\" missing, found " + c, 1);
+        }
+
+        return 1;
+    }
+
+    private int handleClosingTwine(char c) throws SyntaxError {
+        if (c == '>') {
+            if (tree.getElement() == null) {
+                throw new SyntaxError("Unknown Twine tag", 2);
+            }
+            if (tree.getElement().single) {
+                throw new SyntaxError("Single Twine tag used as closing Tag: " + tree.getElement().tag, 2);
+            }
+            if (logicTags.contains(tree.getElement().tag)) {
+                k = new KnownLogicElement(line, pos, tree.getElement().tag, true);
+            } else {
+                k = new KnownTwineElement(line, pos, false, tree.getElement().tag);
+            }
+            state = -6;
+            return 1;
+        }
+
+        tree = tree.getBranch(c);
+        if (tree == null) {
+            state = 3;
+            throw new SyntaxError("Unknown Twine closing tag or closing \">>\" missing, found " + c, 1);
+        }
+
+        return 1;
+    }
+
     @Override
     public String getShortDescription() {
         StringBuilder builder = new StringBuilder();
-        builder.append(line).append(":").append(pos).append(" ");
+        builder.append('[').append(line).append(":").append(pos).append("] ");
         switch (state) {
             case 0:
                 builder.append("<");
@@ -182,31 +323,37 @@ public class AngleBracketElement extends Element {
                 builder.append("<<");
                 break;
             case -1:
-                builder.append("</");
+                builder.append("<</");
                 break;
             case 2:
-                builder.append("<<???");
+                builder.append("<<").append(tree.getPath());
+                break;
+            case -2:
+                builder.append("<</").append(tree.getPath());
                 break;
             case 3:
-                builder.append("<<???>");
+                builder.append("<<??? ???");
                 break;
             case 4:
-                builder.append("<").append(htmlTree.getPath());
+                builder.append("<<?").append(tree.getPath()).append(" ???");
+                break;
+            case -3:
+                builder.append("<<??? ???>");
                 break;
             case -4:
-                builder.append("</").append(htmlTree.getPath());
+                builder.append("<<?").append(tree.getPath()).append(" ???>");
                 break;
             case 5:
-                builder.append("<").append(htmlTree.getPath()).append(" ???");
+                builder.append("<").append(tree.getPath()).append(" ???");
                 break;
             case -5:
-                builder.append("</").append(htmlTree.getPath());
+                builder.append("</").append(tree.getPath());
                 break;
             case 6:
-                builder.append("<").append(htmlTree.getPath()).append(" ???");
+                builder.append("<").append(tree.getPath()).append(" ???");
                 break;
             default:
-                throw new UnknownStateException(state);
+                //throw new UnknownStateException(state);
         }
         return builder.toString();
     }
diff --git a/devTools/javaSanityCheck/src/element/CommentElement.java b/devTools/javaSanityCheck/src/element/CommentElement.java
new file mode 100644
index 00000000000..3a3cc12aff9
--- /dev/null
+++ b/devTools/javaSanityCheck/src/element/CommentElement.java
@@ -0,0 +1,66 @@
+package org.arkerthan.sanityCheck.element;
+
+import org.arkerthan.sanityCheck.SyntaxError;
+import org.arkerthan.sanityCheck.UnknownStateException;
+
+public class CommentElement extends Element {
+    int state = 0;
+    /*
+    0 - /
+    1 - /*???
+    2 - /*???*
+    3 - /%???
+    4 - /%???%
+     */
+
+    public CommentElement(int line, int pos) {
+        super(line, pos);
+    }
+
+    @Override
+    public int handleChar(char c) throws SyntaxError {
+        switch (state) {
+            case 0:
+                if (c == '*') {
+                    state = 1;
+                } else if (c == '%') {
+                    state = 3;
+                } else if (c == '>') {
+                    throw new SyntaxError("XHTML style closure", 4, true);
+                } else {
+                    return 4;
+                }
+                break;
+            case 1:
+                if (c == '*') {
+                    state = 2;
+                }
+                break;
+            case 2:
+                if (c == '/') {
+                    return 2;
+                }
+                state = 1;
+                break;
+            case 3:
+                if (c == '%') {
+                    state = 4;
+                }
+                break;
+            case 4:
+                if (c == '/') {
+                    return 2;
+                }
+                state = 3;
+                break;
+            default:
+                throw new UnknownStateException(state);
+        }
+        return 1;
+    }
+
+    @Override
+    public String getShortDescription() {
+        return null;
+    }
+}
diff --git a/devTools/javaSanityCheck/src/element/Element.java b/devTools/javaSanityCheck/src/element/Element.java
index 53934268618..b0f99fa904f 100644
--- a/devTools/javaSanityCheck/src/element/Element.java
+++ b/devTools/javaSanityCheck/src/element/Element.java
@@ -3,13 +3,12 @@ package org.arkerthan.sanityCheck.element;
 import org.arkerthan.sanityCheck.SyntaxError;
 
 public abstract class Element {
-    protected KnownHtmlElement k;
+    protected KnownElement k;
     protected int line, pos;
 
     /**
-     *
      * @param line Line the instance was created
-     * @param pos Position in line the instance was created
+     * @param pos  Position in line the instance was created
      */
     protected Element(int line, int pos) {
         this.line = line;
@@ -22,6 +21,7 @@ public abstract class Element {
      * 1 - the Element changed state
      * 2 - the Element is finished
      * 3 - the Element is finished and a KnownHtmlElement was generated
+     * 4 - the Element is finished and the char is still open for use
      *
      * @param c
      * @return
@@ -29,12 +29,11 @@ public abstract class Element {
      */
     public abstract int handleChar(char c) throws SyntaxError;
 
-    public KnownHtmlElement getKnownElement() {
+    public KnownElement getKnownElement() {
         return k;
     }
 
     /**
-     *
      * @return a short description usually based on state and position of the Element
      */
     public abstract String getShortDescription();
diff --git a/devTools/javaSanityCheck/src/element/KnownElement.java b/devTools/javaSanityCheck/src/element/KnownElement.java
new file mode 100644
index 00000000000..305be2fe652
--- /dev/null
+++ b/devTools/javaSanityCheck/src/element/KnownElement.java
@@ -0,0 +1,31 @@
+package org.arkerthan.sanityCheck.element;
+
+import org.arkerthan.sanityCheck.SyntaxError;
+
+public abstract class KnownElement extends Element {
+
+    public KnownElement(int line, int pos) {
+        super(line, pos);
+    }
+
+    /**
+     * @return true, if it needs another Known Element to close it.
+     */
+    public abstract boolean isOpening();
+
+    /**
+     * @return true if it closes another Element.
+     */
+    public abstract boolean isClosing();
+
+    /**
+     * @param k Element to be checked
+     * @return true if given Element closes Element
+     */
+    public abstract boolean isMatchingElement(KnownElement k);
+
+    @Override
+    public int handleChar(char c) throws SyntaxError {
+        return 0;
+    }
+}
diff --git a/devTools/javaSanityCheck/src/element/KnownHtmlElement.java b/devTools/javaSanityCheck/src/element/KnownHtmlElement.java
index b3b13673378..d086a74bc54 100644
--- a/devTools/javaSanityCheck/src/element/KnownHtmlElement.java
+++ b/devTools/javaSanityCheck/src/element/KnownHtmlElement.java
@@ -1,6 +1,6 @@
 package org.arkerthan.sanityCheck.element;
 
-public class KnownHtmlElement extends Element {
+public class KnownHtmlElement extends KnownElement {
 
     private boolean opening;
     private String statement;
@@ -11,43 +11,31 @@ public class KnownHtmlElement extends Element {
         this.statement = statement;
     }
 
-    @Override
-    public int handleChar(char c) {
-        return 0;
-    }
-
     @Override
     public String getShortDescription() {
         StringBuilder builder = new StringBuilder();
-        builder.append(line).append(":").append(pos).append(" <");
-        if(!opening){
+        builder.append('[').append(line).append(":").append(pos).append("] <");
+        if (!opening) {
             builder.append("/");
         }
-        return builder.append(statement).toString();
+        return builder.append(statement).append(">").toString();
     }
 
-    /**
-     * @return true, if it needs another Known Element to close it, false if it closes another element.
-     */
+    @Override
     public boolean isOpening() {
         return opening;
     }
 
-    /**
-     * @param k Element to be checked
-     * @return true if given Element closes Element
-     */
-    public boolean isMatchingElement(KnownHtmlElement k) {
-        return k.statement.equals(this.statement);
+    @Override
+    public boolean isClosing() {
+        return !opening;
     }
 
-    /**
-     * Returns, if isOpening is true, the needed statement for closing,
-     * otherwise the statement that generated it.
-     *
-     * @return statement
-     */
-    public String getStatement() {
-        return statement;
+    @Override
+    public boolean isMatchingElement(KnownElement k) {
+        if (k instanceof KnownHtmlElement) {
+            return ((KnownHtmlElement) k).statement.equals(this.statement);
+        }
+        return false;
     }
 }
diff --git a/devTools/javaSanityCheck/src/element/KnownLogicElement.java b/devTools/javaSanityCheck/src/element/KnownLogicElement.java
new file mode 100644
index 00000000000..502abde93a2
--- /dev/null
+++ b/devTools/javaSanityCheck/src/element/KnownLogicElement.java
@@ -0,0 +1,117 @@
+package org.arkerthan.sanityCheck.element;
+
+import org.arkerthan.sanityCheck.DisallowedTagException;
+import org.arkerthan.sanityCheck.UnknownStateException;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class KnownLogicElement extends KnownElement {
+    private static final List<String> allowedTags = Arrays.asList("if", "elseif", "else");
+    private final int state;
+    private boolean last;
+    /*
+    0 - if
+    1 - elseif
+    2 - else
+    3 - switch
+    4 - case
+    5 - default
+     */
+
+    public KnownLogicElement(int line, int pos, String tag, boolean last) {
+        this(line, pos, tag);
+        this.last = last;
+    }
+
+    public KnownLogicElement(int line, int pos, String tag) {
+        super(line, pos);
+        switch (tag) {
+            case "if":
+                state = 0;
+                break;
+            case "elseif":
+                state = 1;
+                break;
+            case "else":
+                state = 2;
+                break;
+            case "switch":
+                state = 3;
+                break;
+            case "case":
+                state = 4;
+                break;
+            case "default":
+                state = 5;
+                break;
+            default:
+                throw new DisallowedTagException(tag);
+        }
+        last = false;
+    }
+
+    @Override
+    public boolean isOpening() {
+        return !last;
+    }
+
+    @Override
+    public boolean isClosing() {
+        return (state != 0 && state != 3) || last;
+    }
+
+    @Override
+    public boolean isMatchingElement(KnownElement k) {
+        if (!(k instanceof KnownLogicElement)) {
+            return false;
+        }
+        KnownLogicElement l = (KnownLogicElement) k;
+        switch (state) {
+            case 0:
+            case 1:
+                return l.state == 1 || l.state == 2 || (l.state == 0 && l.last);
+            case 2:
+                return l.state == 0 && l.last;
+            case 3:
+            case 4:
+                return l.state == 3 || l.state == 4;
+            case 5:
+                return l.state == 3 && l.last;
+            default:
+                throw new UnknownStateException(state);
+        }
+    }
+
+    @Override
+    public String getShortDescription() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("[").append(line).append(":").append(pos).append("] <<");
+        if (last) {
+            builder.append('/');
+        }
+        switch (state) {
+            case 0:
+                builder.append("if");
+                break;
+            case 1:
+                builder.append("elseif");
+                break;
+            case 2:
+                builder.append("else");
+                break;
+            case 3:
+                builder.append("switch");
+                break;
+            case 4:
+                builder.append("case");
+                break;
+            case 5:
+                builder.append("default");
+                break;
+            default:
+                throw new UnknownStateException(state);
+        }
+        return builder.append(">>").toString();
+    }
+}
diff --git a/devTools/javaSanityCheck/src/element/KnownTwineElement.java b/devTools/javaSanityCheck/src/element/KnownTwineElement.java
new file mode 100644
index 00000000000..24003fd00be
--- /dev/null
+++ b/devTools/javaSanityCheck/src/element/KnownTwineElement.java
@@ -0,0 +1,41 @@
+package org.arkerthan.sanityCheck.element;
+
+public class KnownTwineElement extends KnownElement {
+
+    private boolean opening;
+    private String statement;
+
+    public KnownTwineElement(int line, int pos, boolean opening, String statement) {
+        super(line, pos);
+        this.opening = opening;
+        this.statement = statement;
+    }
+
+    @Override
+    public String getShortDescription() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("[").append(line).append(":").append(pos).append("] <<");
+        if (!opening) {
+            builder.append("/");
+        }
+        return builder.append(statement).append(">>").toString();
+    }
+
+    @Override
+    public boolean isOpening() {
+        return opening;
+    }
+
+    @Override
+    public boolean isClosing() {
+        return !opening;
+    }
+
+    @Override
+    public boolean isMatchingElement(KnownElement k) {
+        if (k instanceof KnownTwineElement) {
+            return ((KnownTwineElement) k).statement.equals(this.statement);
+        }
+        return false;
+    }
+}
diff --git a/devTools/javaSanityCheck/src/tag/HtmlTag.java b/devTools/javaSanityCheck/src/tag/HtmlTag.java
deleted file mode 100644
index 70bff2c5a32..00000000000
--- a/devTools/javaSanityCheck/src/tag/HtmlTag.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.arkerthan.sanityCheck.tag;
-
-public class HtmlTag extends Tag {
-    public HtmlTag(String tag, boolean single) {
-        super(tag, single);
-    }
-}
diff --git a/devTools/javaSanityCheck/twineTags b/devTools/javaSanityCheck/twineTags
index d8df5639a52..e1dea71621b 100644
--- a/devTools/javaSanityCheck/twineTags
+++ b/devTools/javaSanityCheck/twineTags
@@ -7,123 +7,17 @@
 #Do not add HTML Tags here.
 #Characters outside of ASCII scope are not supported.
 #
-#widgets
-amputeeDescription;0
-assignmentFilter;0
-resetAssignmentFilter;0
-accentDescription;0
-collarDescription;0
-AnusDescription;0
-armsTatDescription;0
-BoobsDescription;0
-boobBrandDescription;0
-BellyInflationDescription;0
-BellyImplantDescription;0
-BellyDescription;0
-ButtDescription;0
-showallAssignmentFilter;0
-boobsShapeDescription;0
-boobsExtraDescription;0
-boobsTatDescription;0
-shouldersDescription;0
-nipplesDescription;0
-crotchDescription;0
-listOfSlavesWithParent;0
-redisplayFamily;0
-parentName;0
-listOfSlavesWithSameParent;0
-nurseryAssignmentFilter;0
-dickDescription;0
-vaginaDescription;0
-SlaveInteractImpreg;0
-SlaveInteractFertility;0
-SlaveInteractSexOption;0
-SlaveInteractAnalSexOption;0
-SlaveInteractGropeOption;0
-SlaveInteractDickGropeOption;0
-SlaveInteractAnalGropeOption;0
-SlaveInteractDrugs;0
-nipplesPiercingDescription;0
-areolaeDescription;0
-nailsDescription;0
-backTatDescription;0
-pregnancyDescription;0
-ClothingDescription;0
-InscripDesc;0
-clothingCorsetDescription;0
-SlaveArt;0
-SlaveSort;0
-shouldersTatDescription;0
-earDescription;0
-upperFaceDescription;0
-HairDescription;0
-earPiercingDescription;0
-nosePiercingDescription;0
-eyebrowPiercingDescription;0
-customTatDescription;0
-faceDescription;0
-mouthDescription;0
-setLocalPronouns;0
-eyeDescription;0
-brandDescription;0
-Family;0
-chastityPiercingDescription;0
-footwearDescription;0
-HairClothingDescription;0
-FlowerDesc;0
-ImageDesc;0
-waistDescription;0
-heightImplantDescription;0
-BodyguardWeapon;0
-CorsetPiercingDescription;0
-heelDescription;0
-FarmyardStatistics;0
-skinDescription;0
-Master;0
-setPlayerPronouns;0
-farmyardAssignmentFilter;0
-setAssistantPronouns;0
-OptionAbbreviateDevotion;0
-OptionAbbreviateDiet;0
-OptionAbbreviateDrugs;0
-OptionAbbreviateHormoneBalance;0
-OptionAbbreviateGenitalia;0
-OptionAbbreviatePhysicals;0
-OptionAbbreviateOrigins;0
-OptionAbbreviateRulesets;0
-OptionAbbreviateSidebar;0
-OptionAbbreviateMissing;0
-OptionAbbreviateSkills;0
-OptionAbbreviateMental;0
-OptionAbbreviateNationality;0
-OptionAbbreviateClothes;0
-OptionAbbreviateRace;0
-OptionAbbreviateRules;0
-OptionAbbreviateHealth;0
-OptionLineSeparations;0
-OptionSortBy;0
-OptionRulesAssistantMain;0
-OptionDisplayAssignments;0
-OptionSortOrder;0
-OptionSortMain;0
-OptionSummaryStats;0
-s;0
-c;0
-ss;0
-S;0
-x;0
-z;0
-say;0
-Sh;0
-#
 #twine tags
 capture;1
 continue;0
 for;1
+#does foreach really exist?
+foreach;1
 goto;0
 htag;1
 include;0
 link;1
+nobr;1
 print;0
 replace;1
 run;0
@@ -134,7 +28,7 @@ textbox;0
 timed;1
 unset;0
 widget;1
-=;
+=;0
 #
 # Twine logic ### DO NOT TOUCH ###
 if;1
-- 
GitLab