public static IndexTree cloneTree( IndexTree tree ) { if( tree == null ) return null; IndexTree clone = new IndexTree( tree.indexA, tree.indexB, tree.offsetA, tree.offsetB, tree.data, null ); if (tree.data != null && tree.data.GetType().GetMethod("clone") != null) clone.data = tree.data.GetType().InvokeMember("clone", BindingFlags.InvokeMethod, null, tree.data, new object[] { }); IndexTree cloneNode; int i = -1; int l = tree.nodes.Count; while( ++i < l ) { cloneNode = cloneTree( tree.nodes[i] ); cloneNode.parentNode = clone; clone.nodes.Add(cloneNode); } return clone; }
public static List<IndexTree> flattenTree( IndexTree tree ) { if( tree == null ) return null; IndexTree t; List<IndexTree> flats = new List<IndexTree>(); int offsetA = tree.offsetA; int prevIdxB = tree.indexA; int i = -1; int l = tree.nodes.Count; while( ++i < l ) { t = tree.nodes[i]; if( t == null ) continue; IndexTree fTree = new IndexTree(prevIdxB, t.indexA, offsetA, 0, tree.data, tree.parentNode); flats.Add( fTree ); flats.AddRange( flattenTree( t ) ); prevIdxB = t.indexB; offsetA = 0; } flats.Add( new IndexTree( prevIdxB, tree.indexB, offsetA, tree.offsetB, tree.data, tree.parentNode ) ); return flats; }
public static IndexTree cloneTree(IndexTree tree) { if (tree == null) { return(null); } IndexTree clone = new IndexTree(tree.indexA, tree.indexB, tree.offsetA, tree.offsetB, tree.data, null); if (tree.data != null && tree.data.GetType().GetMethod("clone") != null) { clone.data = tree.data.GetType().InvokeMember("clone", BindingFlags.InvokeMethod, null, tree.data, new object[] { }); } IndexTree cloneNode; int i = -1; int l = tree.nodes.Count; while (++i < l) { cloneNode = cloneTree(tree.nodes[i]); cloneNode.parentNode = clone; clone.nodes.Add(cloneNode); } return(clone); }
private static int _normalizeTree(IndexTree tree, int offset) { if (tree == null) { return(offset); } tree.indexA -= offset; offset += tree.offsetA; tree.offsetA = 0; if (tree.nodes != null) { int i = -1; int l = tree.nodes.Count; while (++i < l) { offset = _normalizeTree(tree.nodes[i], offset); } } offset -= tree.offsetB; tree.indexB -= offset; tree.offsetB = 0; return(offset); }
public static String assembleOutput(String input, IndexTree tree) { if (string.IsNullOrEmpty(input) || tree == null) { return(null); } String outStr = ""; List <IndexTree> flat = IndexTree.flattenTree(tree); int idxA, idxB; int i = -1; int l = flat.Count; while (++i < l) { idxA = flat[i].indexA + flat[i].offsetA; idxB = flat[i].indexB + flat[i].offsetB; if (idxA > idxB) { return(input); } outStr += input.Substring(idxA, idxB - idxA); } return(outStr); }
public IndexTree( int indexA, int indexB, int offsetA, int offsetB, object data, IndexTree parentNode ) { _init(indexA, indexB, offsetA, offsetB, data, parentNode); }
public IndexTree(int indexA, int indexB, int offsetA, int offsetB, object data, IndexTree parentNode) { _init(indexA, indexB, offsetA, offsetB, data, parentNode); }
private IndexTree _parse() { pairTagMatcher.input = input; List <IPairTagMatch> openers = _findAllOpeners(); IndexTree tree = _buildTree(openers); return(tree); }
public IndexTree parse() { lastTree = null; if (pairTagMatcher == null || this.input == null || this.input.Length < 1) return null; lastTree = _parse(); return lastTree; }
public IndexTree parse() { lastTree = null; if (pairTagMatcher == null || string.IsNullOrEmpty(this.input)) return null; lastTree = _parse(); return lastTree; }
private IndexTree _buildTree(List <IPairTagMatch> openers) { uint inputL = (uint)input.Length; Boolean closerOutOfBounds; int closerStartAt; Dictionary <int, IPairTagMatch> closerIndices = new Dictionary <int, IPairTagMatch>(); IPairTagMatch mOp; IPairTagMatch mCl; IndexTree rootTree = new IndexTree(0, (int)inputL, 0, 0, null, null); int i = openers.Count; while (i-- > 0) { mOp = openers[i]; closerStartAt = (int)(mOp.tagIndex + mOp.tagLength); closerOutOfBounds = false; while (true) { mCl = pairTagMatcher.searchCloserFor(mOp, (uint)closerStartAt); if (mCl == null) { mCl = new VoidCloserTagMatch((int)inputL); closerOutOfBounds = true; } if (!closerIndices.ContainsKey(mCl.tagIndex)) { if (mCl.tagIndex < inputL) { closerIndices[mCl.tagIndex] = mCl; } IndexTree.insertLeaf(rootTree, new IndexTree(mOp.tagIndex, (int)(mCl.tagIndex + mCl.tagLength), (int)(mOp.tagLength), (int)(-mCl.tagLength), new PairTag(mOp, mCl), null)); break; } if (closerOutOfBounds) { break; } else if (mCl != null) { closerStartAt = mCl.tagIndex + 1; } } } return(rootTree); }
public static IndexTree getRootNode( IndexTree tree ) { if( tree == null ) return null; IndexTree r = tree; while( r.parentNode != null ) r = r.parentNode; return r; }
public IndexTree parse() { lastTree = null; if (pairTagMatcher == null || this.input == null || this.input.Length < 1) { return(null); } lastTree = _parse(); return(lastTree); }
public IndexTree parse() { lastTree = null; if (pairTagMatcher == null || string.IsNullOrEmpty(this.input)) { return(null); } lastTree = _parse(); return(lastTree); }
public static BBCodeStyle getNodeStyle(IndexTree tree) { if (tree == null) return null; IPairTag pairTag = tree.data as IPairTag; if (pairTag == null) return null; BBCodeTagMatch tm = pairTag.openerMatch as BBCodeTagMatch; if (tm == null) return null; return tm.bbCodeStyle; }
private IndexTree _buildTree(List<IPairTagMatch> openers) { uint inputL = (uint)input.Length; Boolean closerOutOfBounds; int closerStartAt; Dictionary<int, IPairTagMatch> closerIndices = new Dictionary<int, IPairTagMatch>(); IPairTagMatch mOp; IPairTagMatch mCl; IndexTree rootTree = new IndexTree(0, (int)inputL, 0, 0, null, null); int i = openers.Count; while (i-- > 0) { mOp = openers[i]; closerStartAt = (int)(mOp.tagIndex + mOp.tagLength); closerOutOfBounds = false; while (true) { mCl = pairTagMatcher.searchCloserFor(mOp, (uint)closerStartAt); if (mCl == null) { mCl = new VoidCloserTagMatch((int)inputL); closerOutOfBounds = true; } if (!closerIndices.ContainsKey(mCl.tagIndex)) { if (mCl.tagIndex < inputL) closerIndices[mCl.tagIndex] = mCl; IndexTree.insertLeaf(rootTree, new IndexTree(mOp.tagIndex, (int)(mCl.tagIndex + mCl.tagLength), (int)(mOp.tagLength), (int)(-mCl.tagLength), new PairTag(mOp, mCl), null)); break; } if (closerOutOfBounds) break; else if (mCl != null) closerStartAt = mCl.tagIndex + 1; } } return rootTree; }
private void _init(int indexA, int indexB, int offsetA, int offsetB, object data, IndexTree parentNode) { this.indexA = indexA; this.indexB = indexB; this.offsetA = offsetA; this.offsetB = offsetB; this.data = data; this.parentNode = parentNode; nodes = new List <IndexTree>(); }
public static IndexTree getRootNode(IndexTree tree) { if (tree == null) { return(null); } IndexTree r = tree; while (r.parentNode != null) { r = r.parentNode; } return(r); }
public static BBCodeStyle getCascadedNodeStyle(IndexTree tree) { if (tree == null) return null; List<BBCodeStyle> styleHierarchy = new List<BBCodeStyle>(); IndexTree currTree = tree; while (currTree != null) { styleHierarchy.Add(getNodeStyle(currTree)); currTree = currTree.parentNode; } styleHierarchy.Reverse(); return BBCodeStyle.fuseStyleHierarchy(styleHierarchy); }
public static BBCodeStyle getCascadedNodeStyle(IndexTree tree) { if (tree == null) { return(null); } List <BBCodeStyle> styleHierarchy = new List <BBCodeStyle>(); IndexTree currTree = tree; while (currTree != null) { styleHierarchy.Add(getNodeStyle(currTree)); currTree = currTree.parentNode; } styleHierarchy.Reverse(); return(BBCodeStyle.fuseStyleHierarchy(styleHierarchy)); }
public static String treeToString(IndexTree tree, String space, Boolean noEolAndEnd) { if (tree == null) { return(null); } String s = ""; if (!noEolAndEnd) { s += "\n"; } s += space + "<tree" + " indexA=" + tree.indexA + " indexB=" + tree.indexB + " offsetA=" + tree.offsetA + " offsetB=" + tree.offsetB + " nodes=" + tree.nodes.Count + " data='" + (tree.data == null ? "null" : tree.data.ToString()) + "'" + " root='" + (getRootNode(tree).data == null ? "null" : getRootNode(tree).data.ToString()) + "'" + ">"; int i = -1; int l = tree.nodes.Count; while (++i < l) { s += treeToString(tree.nodes[i], space + " ", noEolAndEnd); } if (!noEolAndEnd) { s += "\n" + space + "</>"; } return(s); }
public static String assembleOutput(String input, IndexTree tree) { if (input == null || input.Length < 1 || tree == null) return null; String outStr = ""; List<IndexTree> flat = IndexTree.flattenTree(tree); int idxA, idxB; int i = -1; int l = flat.Count; while (++i < l) { idxA = flat[i].indexA + flat[i].offsetA; idxB = flat[i].indexB + flat[i].offsetB; if (idxA > idxB) return input; outStr += input.Substring(idxA, idxB - idxA); } return outStr; }
public static BBCodeStyle getNodeStyle(IndexTree tree) { if (tree == null) { return(null); } IPairTag pairTag = tree.data as IPairTag; if (pairTag == null) { return(null); } BBCodeTagMatch tm = pairTag.openerMatch as BBCodeTagMatch; if (tm == null) { return(null); } return(tm.bbCodeStyle); }
public static List <IndexTree> flattenTree(IndexTree tree) { if (tree == null) { return(null); } IndexTree t; List <IndexTree> flats = new List <IndexTree>(); int offsetA = tree.offsetA; int prevIdxB = tree.indexA; int i = -1; int l = tree.nodes.Count; while (++i < l) { t = tree.nodes[i]; if (t == null) { continue; } IndexTree fTree = new IndexTree(prevIdxB, t.indexA, offsetA, 0, tree.data, tree.parentNode); flats.Add(fTree); flats.AddRange(flattenTree(t)); prevIdxB = t.indexB; offsetA = 0; } flats.Add(new IndexTree(prevIdxB, tree.indexB, offsetA, tree.offsetB, tree.data, tree.parentNode)); return(flats); }
private void _init( int indexA, int indexB, int offsetA, int offsetB, object data, IndexTree parentNode ) { this.indexA = indexA; this.indexB = indexB; this.offsetA = offsetA; this.offsetB = offsetB; this.data = data; this.parentNode = parentNode; nodes = new List<IndexTree>(); }
public static Boolean insertLeaf( IndexTree tree, IndexTree leaf ) { if( tree == null || leaf == null ) return false; if( leaf.indexA < tree.indexA && leaf.indexB > tree.indexB ) { // trace( "leaf is parent" ); leaf.parentNode = tree.parentNode; tree.parentNode = null; return insertLeaf( leaf, tree ); } if( !(leaf.indexA >= tree.indexA && leaf.indexB <= tree.indexB) ) { // trace( ">> or << out of bounds" ); if( tree.parentNode != null ) return insertLeaf( tree.parentNode, leaf ); return false; } if( !(leaf.indexA >= tree.indexA && leaf.indexB <= tree.indexB) ) { // trace( "incorrect out of bounds" ); return false; } if( tree.nodes == null ) tree.nodes = new List<IndexTree>(); // find where in subnodes it can be placed; int i = tree.nodes.Count; if( i == 0 ) { // trace( "push in subnodes[0]" ); leaf.parentNode = tree; tree.nodes.Add( leaf ); return true; } IndexTree currNode; int prevIdxA = tree.indexB; int currIdxA = -1; int prevGreatA = -1; int prevLessB = -1; while( i-- > -1 ) { if( i > -1 ) { currNode = tree.nodes[i]; currIdxA = currNode.indexB; } else { currIdxA = tree.indexA; } if( leaf.indexA >= currIdxA && leaf.indexB <= prevIdxA ) { // trace( "push in subnodes after [" + i + "]" ); leaf.parentNode = tree; // tree.nodes.splice( i+1, 0, leaf); tree.nodes.Insert(i + 1, leaf); return true; } if( i < 0 ) break; currNode = tree.nodes[i]; if( leaf.indexA >= currNode.indexA && leaf.indexB <= currNode.indexB ) { // trace( "insertLeaf in subnode[" + i + "]" ); return insertLeaf( currNode, leaf ); } if( leaf.indexB >= currNode.indexB && i > prevLessB ) prevLessB = i; if( leaf.indexA <= currNode.indexA ) prevGreatA = i; prevIdxA = tree.nodes[i].indexA; } if( prevGreatA > -1 && prevLessB > -1 ) { // trace("Reinserting subnodes"); leaf.parentNode = tree; List<IndexTree> cuttedNodes = new List<IndexTree>(); int k = 1 + prevLessB - prevGreatA; while( k-- > prevGreatA ) { cuttedNodes.Add( tree.nodes[k] ); tree.nodes.RemoveAt( k ); } cuttedNodes.Reverse(); tree.nodes.Insert( prevGreatA, leaf ); /* tree.nodes.splice( prevGreatA, 1 + prevLessB - prevGreatA, leaf ); */ // trace("cuttedNodes.length: " + cuttedNodes.length); i = cuttedNodes.Count; while( i-- > 0 ) { cuttedNodes[i].parentNode = null; insertLeaf( leaf, cuttedNodes[i] ); } return true; } // throw new Error("Leaf cannot be inserted"); return false; }
public static String treeToString( IndexTree tree, String space, Boolean noEolAndEnd ) { if( tree == null ) return null; String s = ""; if( !noEolAndEnd ) s += "\n"; s += space + "<tree" + " indexA=" + tree.indexA.ToString() + " indexB=" + tree.indexB.ToString() + " offsetA=" + tree.offsetA.ToString() + " offsetB=" + tree.offsetB.ToString() + " nodes=" + tree.nodes.Count.ToString() + " data='" + (tree.data == null ? "null" : tree.data.ToString()) + "'" + " root='" + (getRootNode(tree).data == null ? "null" : getRootNode(tree).data.ToString()) + "'" + ">"; int i = -1; int l = tree.nodes.Count; while( ++i < l ) { s += treeToString( tree.nodes[i], space + " ", noEolAndEnd ); } if( !noEolAndEnd ) s += "\n" + space + "</>"; return s; }
public static String treeToString( IndexTree tree ) { return treeToString( tree, "", false ); }
private static int _normalizeTree( IndexTree tree, int offset ) { if( tree == null ) return offset; tree.indexA -= offset; offset += tree.offsetA; tree.offsetA = 0; if( tree.nodes != null ) { int i = -1; int l = tree.nodes.Count; while( ++i < l ) { offset = _normalizeTree( tree.nodes[i], offset ); } } offset -= tree.offsetB; tree.indexB -= offset; tree.offsetB = 0; return offset; }
public static void normalizeTree( IndexTree tree ) { _normalizeTree( tree, 0 ); }
public static void applyStyleTreeToTextbox(RichTextBox tf, String input, IndexTree bbCodeTree) { if (tf == null || bbCodeTree == null || string.IsNullOrEmpty(input)) { return; } tf.Text = ""; BBCodeStyle rootStyle = new BBCodeStyle(); rootStyle.isAbsFontSize = false; rootStyle.fontName = tf.Font.Name; rootStyle.fontSize = tf.Font.Size; rootStyle.isAbsFontSize = true; rootStyle.foreColor = new BBCodeStyle.Color((uint)0xFF000000 | (uint)(tf.SelectionColor.ToArgb() & (int)0xFFFFFF), BBCodeStyle.Mode.NORMAL); rootStyle.backColor = new BBCodeStyle.Color((uint)0xFF000000 | (uint)(tf.SelectionBackColor.ToArgb() & (int)0xFFFFFF), BBCodeStyle.Mode.NORMAL); rootStyle.isBold = tf.Font.Bold ? StateMode.ON : StateMode.OFF; rootStyle.isItalic = tf.Font.Italic ? StateMode.ON : StateMode.OFF; rootStyle.isStriked = tf.Font.Strikeout ? StateMode.ON : StateMode.OFF; rootStyle.isUnderlined = tf.Font.Underline ? StateMode.ON : StateMode.OFF; PairTag rootPair = new PairTag(new BBCodeTagMatch(true, 0, "", "", "", 0, 0, false), new VoidCloserTagMatch(input.Length)); (rootPair.openerMatch as BBCodeTagMatch).bbCodeStyle = rootStyle; bbCodeTree = IndexTree.cloneTree(bbCodeTree); bbCodeTree.data = rootPair; List <IndexTree> flatTree = IndexTree.flattenTree(bbCodeTree); String flatText = assembleOutput(input, bbCodeTree); String corrFlatText = _replaceEnclosures(flatText); IndexTree.normalizeTree(bbCodeTree); flatTree = IndexTree.flattenTree(bbCodeTree); tf.Text = corrFlatText /*flatText*/; if (flatText == input) { return; } String currText; String currCorrText; int offsetA = 0; int offsetB = 0; int idxA, idxB; int i = -1; int l = flatTree.Count; while (++i < l) { idxA = flatTree[i].indexA; idxB = flatTree[i].indexB; currText = flatText.Substring(idxA, idxB - idxA); currCorrText = _replaceEnclosures(currText); offsetB = currCorrText.Length + idxA - idxB; applyStyleToTextbox(getCascadedNodeStyle(flatTree[i]), tf, idxA + offsetA, idxB + offsetA + offsetB); offsetA += offsetB; } tf.Select(tf.Text.Length, tf.Text.Length); }
public static String treeToString(IndexTree tree) { return(treeToString(tree, "", false)); }
public static Boolean insertLeaf(IndexTree tree, IndexTree leaf) { if (tree == null || leaf == null) { return(false); } if (leaf.indexA < tree.indexA && leaf.indexB > tree.indexB) { // trace( "leaf is parent" ); leaf.parentNode = tree.parentNode; tree.parentNode = null; return(insertLeaf(leaf, tree)); } if (!(leaf.indexA >= tree.indexA && leaf.indexB <= tree.indexB)) { // trace( ">> or << out of bounds" ); if (tree.parentNode != null) { return(insertLeaf(tree.parentNode, leaf)); } return(false); } if (!(leaf.indexA >= tree.indexA && leaf.indexB <= tree.indexB)) { // trace( "incorrect out of bounds" ); return(false); } if (tree.nodes == null) { tree.nodes = new List <IndexTree>(); } // find where in subnodes it can be placed; int i = tree.nodes.Count; if (i == 0) { // trace( "push in subnodes[0]" ); leaf.parentNode = tree; tree.nodes.Add(leaf); return(true); } IndexTree currNode; int prevIdxA = tree.indexB; int currIdxA = -1; int prevGreatA = -1; int prevLessB = -1; while (i-- > -1) { if (i > -1) { currNode = tree.nodes[i]; currIdxA = currNode.indexB; } else { currIdxA = tree.indexA; } if (leaf.indexA >= currIdxA && leaf.indexB <= prevIdxA) { // trace( "push in subnodes after [" + i + "]" ); leaf.parentNode = tree; // tree.nodes.splice( i+1, 0, leaf); tree.nodes.Insert(i + 1, leaf); return(true); } if (i < 0) { break; } currNode = tree.nodes[i]; if (leaf.indexA >= currNode.indexA && leaf.indexB <= currNode.indexB) { // trace( "insertLeaf in subnode[" + i + "]" ); return(insertLeaf(currNode, leaf)); } if (leaf.indexB >= currNode.indexB && i > prevLessB) { prevLessB = i; } if (leaf.indexA <= currNode.indexA) { prevGreatA = i; } prevIdxA = tree.nodes[i].indexA; } if (prevGreatA > -1 && prevLessB > -1) { // trace("Reinserting subnodes"); leaf.parentNode = tree; List <IndexTree> cuttedNodes = new List <IndexTree>(); int k = 1 + prevLessB - prevGreatA; while (k-- > prevGreatA) { cuttedNodes.Add(tree.nodes[k]); tree.nodes.RemoveAt(k); } cuttedNodes.Reverse(); tree.nodes.Insert(prevGreatA, leaf); /* * tree.nodes.splice( prevGreatA, * 1 + prevLessB - prevGreatA, * leaf ); */ // trace("cuttedNodes.length: " + cuttedNodes.length); i = cuttedNodes.Count; while (i-- > 0) { cuttedNodes[i].parentNode = null; insertLeaf(leaf, cuttedNodes[i]); } return(true); } // throw new Error("Leaf cannot be inserted"); return(false); }
public static void normalizeTree(IndexTree tree) { _normalizeTree(tree, 0); }
public static void applyStyleTreeToTextbox(RichTextBox tf, String input, IndexTree bbCodeTree) { if (tf == null || bbCodeTree == null || input == null || input.Length < 1) return; tf.Text = ""; BBCodeStyle rootStyle = new BBCodeStyle(); rootStyle.isAbsFontSize = false; rootStyle.fontName = tf.Font.Name; rootStyle.fontSize = tf.Font.Size; rootStyle.isAbsFontSize = true; rootStyle.foreColor = new BBCodeStyle.Color((uint)0xFF000000 | (uint)(tf.SelectionColor.ToArgb() & (int)0xFFFFFF), BBCodeStyle.Mode.NORMAL); rootStyle.backColor = new BBCodeStyle.Color((uint)0xFF000000 | (uint)(tf.SelectionBackColor.ToArgb() & (int)0xFFFFFF), BBCodeStyle.Mode.NORMAL); rootStyle.isBold = tf.Font.Bold ? StateMode.ON : StateMode.OFF; rootStyle.isItalic = tf.Font.Italic ? StateMode.ON : StateMode.OFF; rootStyle.isStriked = tf.Font.Strikeout ? StateMode.ON : StateMode.OFF; rootStyle.isUnderlined = tf.Font.Underline ? StateMode.ON : StateMode.OFF; PairTag rootPair = new PairTag(new BBCodeTagMatch(true, 0, "", "", "", 0, 0, false), new VoidCloserTagMatch(input.Length)); (rootPair.openerMatch as BBCodeTagMatch).bbCodeStyle = rootStyle; bbCodeTree = IndexTree.cloneTree(bbCodeTree); bbCodeTree.data = rootPair; List<IndexTree> flatTree = IndexTree.flattenTree(bbCodeTree); String flatText = BBCodeUtils.assembleOutput(input, bbCodeTree); String corrFlatText = _replaceEnclosures(flatText); IndexTree.normalizeTree(bbCodeTree); flatTree = IndexTree.flattenTree(bbCodeTree); tf.Text = corrFlatText/*flatText*/; if (flatText == input) return; String currText; String currCorrText; int offsetA = 0; int offsetB = 0; int idxA, idxB; int i = -1; int l = flatTree.Count; while (++i < l) { idxA = flatTree[i].indexA; idxB = flatTree[i].indexB; currText = flatText.Substring(idxA, idxB - idxA); currCorrText = _replaceEnclosures(currText); offsetB = currCorrText.Length + idxA - idxB; applyStyleToTextbox(BBCodeUtils.getCascadedNodeStyle(flatTree[i]), tf, idxA + offsetA, idxB + offsetA + offsetB); offsetA += offsetB; } tf.Select(tf.Text.Length, tf.Text.Length); }