// Attach nested region to the child.
        // **Need to be careful to set attributes correctly here.
        public ParseState AddNestedRegion(RelationTreeNode relationNode, SymbolTreeNode snode)
        {
            // Create new child node. *Maintain previous node (depth-first
            // parse).
            ParseState newState = new ParseState();

            // Attributes..
            newState.rootNode       = relationNode;
            newState.numberStrokes  = relationNode.lbt.strokes.Count; // Only need to consume strokes in this sub-region.
            newState.completesParse = false;                          // This branch cannot be the final NT for a rule.

            // Wipe out candidate and previous symbols.
            newState.candidateSymbols         = null;
            newState.previous                 = new PreviousSymbol();
            newState.previous.symbol          = new LexerResult();
            newState.previous.regionsOptional = true;

            /*if (relationNode.lbt.strokes == null)
             *      Console.WriteLine("RELATION NODE LBT: NULL!!");
             * else
             *      Console.WriteLine("RELATION NODE LBT: {0} strokes", relationNode.lbt.strokes.Count);
             */
            newState.previous.symbol.lbt = relationNode.lbt;


            // COMPLETING PARSE?
            //newState.completesParse = previous.parent.

            // Attach region to parent node.
            previous.parent.children.Add(relationNode);

            return(newState);
        }
        public ParseState(ParseState pstate, RelationTreeNode node)
        {
            candidateSymbols = pstate.candidateSymbols;
            numberStrokes    = pstate.numberStrokes;
            completesParse   = pstate.completesParse;
            previous         = pstate.previous;

            // Inherit all attributes, but modify the root node.
            rootNode = node;
        }
        public PartitionResult()
        {
            ABOVE    = new RelationTreeNode("ABOVE", "_partition");
            BELOW    = new RelationTreeNode("BELOW", "_partition");
            CONTAINS = new RelationTreeNode("CONTAINS", "_partition");
            SUPER    = new RelationTreeNode("SUPER", "_partition");
            SUBSC    = new RelationTreeNode("SUBSC", "_partition");

            // Additions.
            TLEFT = new RelationTreeNode("TLEFT", "_partition");
            BLEFT = new RelationTreeNode("BLEFT", "_partition");
        }
        public override ParseTreeNode clone()
        {
            // Node labels and stoke data will be fixed for a given node (ref. only), but children will
            // differ for different parse trees (new copy).
            RelationTreeNode nodeCopy = new RelationTreeNode(relationType, nodeType);

            nodeCopy.strokes = strokes;
            nodeCopy.lbt     = null;
            if (lbt != null)
            {
                nodeCopy.lbt = new LBT(lbt);           // copy lbt
            }
            foreach (ParseTreeNode child in children)
            {
                nodeCopy.children.Add(child.clone());
            }
            return(nodeCopy);
        }
        // include generated mathml from right nodes to siblings to their left (because of mrow)
        virtual public string ChildMathML(string right)
        {
            if (this is RelationTreeNode || this is SymbolTreeNode)
            {
                throw new Exception("Child classes must re-implement this method");
            }

            if (this.children.Count > 0 && (this.children[0] is RelationTreeNode || this.children[0] is SymbolTreeNode))
            {
                string this_symbol = null;

                if (this.children.Count == 2)
                {
                    // one relation
                    string relationship = (this.children[1] as RelationTreeNode).relationType;
                    switch (relationship)
                    {
                    // sqrt
                    case "CONTAINS":
                        this_symbol = String.Format("<msqrt>{0}</msqrt>", this.children[1].ChildMathML(null));
                        break;

                    // supersscript
                    case "SUPER":
                        this_symbol = String.Format("<msup>{0}{1}</msup>", this.children[0].ChildMathML(null), this.children[1].ChildMathML(null));
                        break;

                    // subscript
                    case "SUBSC":
                        this_symbol = String.Format("<msub>{0}{1}</msub>", this.children[0].ChildMathML(null), this.children[1].ChildMathML(null));
                        break;
                    }
                }
                else if (this.children.Count == 3)
                {
                    // frac/sum/etc.
                    string above = null, below = null, this_sym = null;
                    bool   is_frac = false;
                    foreach (ParseTreeNode ptn in this.children)
                    {
                        if (ptn is RelationTreeNode)
                        {
                            RelationTreeNode rtn = null;
                            rtn = ptn as RelationTreeNode;

                            if (rtn.relationType == "ABOVE")
                            {
                                above = rtn.ChildMathML(null);
                            }
                            if (rtn.relationType == "BELOW")
                            {
                                below = rtn.ChildMathML(null);
                            }
                        }
                        else if (ptn is SymbolTreeNode)
                        {
                            SymbolTreeNode stn = ptn as SymbolTreeNode;
                            this_sym = stn.ChildMathML(null);
                            if (stn.nodeType.Equals("-"))
                            {
                                is_frac = true;
                            }
                        }
                    }

                    if (is_frac)
                    {
                        this_symbol = String.Format("<mfrac>{0}{1}</mfrac>", above, below);
                    }
                    else
                    {
                        this_symbol = String.Format("<msubsup>{0}{1}{2}</msubsup>", this_sym, below, above);
                    }
                }
                else
                {
                    for (int k = this.children.Count - 1; k >= 0; k--)
                    {
                        right = this.children[k].ChildMathML(right);
                    }
                }

                if (right == null)
                {
                    return(this_symbol);
                }
                if (this_symbol == null)
                {
                    return(right);
                }

                // something to our right
                return(String.Format("<mrow>{0}{1}</mrow>", this_symbol, right));
            }
            else
            {
                for (int k = this.children.Count - 1; k >= 0; k--)
                {
                    right = this.children[k].ChildMathML(right);
                }
                return(right);
            }
        }
 public ParseState RemoveNestedRegion(RelationTreeNode relationNode)
 {
     previous.parent.children.Remove(relationNode);
     return(this);
 }