public void ReadRules(ParserContext context) { _reader = new XmlTextReader(_filename); string womObject = ""; string pattern = ""; string end = ""; string jump = ""; string optimization = ""; string temp = ""; string[] elements = null; ParserRule rule; while (_reader.Read()) { switch (_reader.NodeType) { case XmlNodeType.Element: switch (_reader.LocalName) { case "Rule": womObject = _reader.GetAttribute("Name"); pattern = _reader.GetAttribute("Pattern"); optimization = _reader.GetAttribute("Optimization"); temp = _reader.GetAttribute("Elements"); if (!String.IsNullOrEmpty(temp)) { elements = temp.Split(','); } if (_reader.AttributeCount == 6) { end = _reader.GetAttribute("End"); jump = _reader.GetAttribute("Jump"); } rule = new ParserRule(womObject, pattern, end, jump, optimization, elements, null, context); context.AddRule(rule); womObject = ""; pattern = ""; end = ""; jump = ""; optimization = ""; elements = null; break; } break; } } }
//this is the main body where the real parsing work is done < 30 lines of code public WomDocument ProcessText(string wikiInput, QualifiedTopicRevision topic, NamespaceManager mgr, bool fragment, int size) { //_stopwatch = Stopwatch.StartNew(); ParserContext savedcontext; bool redo = false; wikiInput = wikiInput.Replace("\r\n\r\n", "\r\n"); if (!fragment) { wikiInput = "\r\n" + wikiInput; } else { while (wikiInput.EndsWith("\r\n")) { wikiInput = wikiInput.Remove(wikiInput.LastIndexOf("\r\n")); } } _womDocument = new WomDocument(null); _womDocument.Fed = _fed; _womDocument.Mgr = mgr; _womDocument.FragmentOnly = fragment; _womDocument.Begin(); int chunk = _chunk; //set the initial chunk size (for cache use) if (size > 0) { chunk = size; } chunkcnt = 1; while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } if (!String.IsNullOrEmpty(wikiInput)) { StringBuilder source = new StringBuilder(); StringBuilder temp = new StringBuilder(); source.AppendLine(externalWikiRef.Replace(wikiInput, new MatchEvaluator(externalWikiRefMatch))); temp.Append(multilinePre.Replace(source.ToString(), new MatchEvaluator(multilinePreMatch))); source = temp; string savedtemp = temp.ToString(); MatchCollection matches; while (source.Length > 0) { string womElement = _context.WomElement; //optimize here by passing in less than the full string when source is very long //this gives a 5 times performance improvement int matchcnt = 0; if (source.Length > chunk * chunkcnt) { matches = _context.RegExp.Matches(source.ToString(0, chunk * chunkcnt)); matchcnt = matches.Count; } else { matches = _context.RegExp.Matches(source.ToString()); matchcnt = matches.Count; } if (matchcnt > 0) { if (matches[0].Index > 0) { _womDocument.SimpleAdd(source.ToString(0, matches[0].Index), womElement, "", _context.RuleList[0]); } int x = 1; if (_context.RegExpStr.StartsWith("(?:") && !matches[0].Value.StartsWith("%")) { x = 0; } int cnt = matches[0].Groups.Count; for (int i = x; i < cnt; i++) { if (matches[0].Groups[i].Success) { if (womElement != "WikiText") { //we are in a child rule set with an end condition //whereas WikiText ends by running out of source or matches if (i == 1) { i = 0; } } if (_womDocument.InTable && _womDocument.InItem && matches[0].Value.StartsWith("%")) { i++; //add one to the index here as we are in womText rules twice for this condition } ParserRule rule = _context.RuleList[i]; savedcontext = _context; string addElement; if (!String.IsNullOrEmpty(rule.WomElement)) { addElement = rule.WomElement; } else { addElement = womElement; } _womDocument.SimpleAdd(matches[0].Value, addElement, rule.Jump, rule); if (_womDocument.ParsedDocument.Contains("<<")) //an error occurred { chunkcnt++; //increase the chunk size and redo redo = true; } else { if (addElement != "WikiStylingEnd") { _context = rule.Context; } //still in a line - only pop one context item else if (matches[0].Value == "%%" || matches[0].Value == "%" || matches[0].Value.Contains("{||")) { _context = _context.ParentRule.ParentContext; } else //done with that line - pop all context back to start { while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } } } break; } } if (!redo) //an error occurred { bool modifyRemove = false; if (womElement == "womListText" && matches[0].Value.Contains("{||")) //need to leave this bit in source { modifyRemove = true; } else if (womElement == "womWikiStyledText" && matches[0].Value == "%") { modifyRemove = true; } if (modifyRemove) { source.Remove(0, matches[0].Index); } else { source.Remove(0, matches[0].Index + matches[0].Length); } } else { //reset and start over with larger chunk source = new StringBuilder(); source.Append(savedtemp); _womDocument = new WomDocument(null); _womDocument.Fed = _fed; _womDocument.Mgr = mgr; _womDocument.FragmentOnly = fragment; _womDocument.Begin(); redo = false; while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } } } else { if (source.Length > chunk * chunkcnt) //no match in that chunk, increase size and retry { source = new StringBuilder(); source.Append(savedtemp); _womDocument = new WomDocument(null); _womDocument.Fed = _fed; _womDocument.Mgr = mgr; _womDocument.FragmentOnly = fragment; _womDocument.Begin(); chunkcnt++; while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } } else { _womDocument.SimpleAdd(source.ToString(), womElement, "", _context.RuleList[0]); source.Length = 0; } } } source = null; temp = null; } _womDocument.End(); if (((bool)_fed.Application["DisableWikiEmoticons"] == false)) //&& (_mgr.DisableNamespaceEmoticons == false)) { MatchCollection emoticonMatches = findEmoticon.Matches(_womDocument.ParsedDocument); if (emoticonMatches.Count > 0) { _womDocument.ConvertEmoticons(emoticonMatches); } } //_stopwatch.Stop(); if (chunkcnt > 1) { mgr.SetProcessTextSize(topic.AsUnqualifiedTopicRevision(), chunk * chunkcnt); } return _womDocument; }
public ParentRule(string womObject, string pattern, string end, string jump, string optimization, string[] elements, ParserContext ruleContext, ParserContext context) : base(womObject, pattern, end, jump, optimization, elements, ruleContext, context) { }
///// <summary> ///// Create a new formatter for a string of input content. ///// </summary> ///// <param name="source">Input wiki string</param> ///// <param name="output">Output object to which output is sent</param> ///// <param name="namespaceManager">The ContentProviderChain that contains the wiki string text</param> ///// <param name="maker">A link maker </param> ///// <param name="external">External wiki map</param> ///// <param name="headingLevelBase">Relative heading level</param> ///// //Formatter(QualifiedTopicRevision topic, string source, WikiOutput output, NamespaceManager namespaceManager, // LinkMaker maker, ExternalReferencesMap external, int headingLevelBase) //{ // _topic = topic; // _source = SplitStringIntoStyledLines(source, LineStyle.Unchanged); // _linkMaker = maker; // NamespaceManager = namespaceManager; // _output = output; // _externalWikiMap = external; // _headingLevelBase = headingLevelBase; //} ///// <summary> ///// Create a new formatter for an input list of StyledLines ///// </summary> ///// <param name="source">Input wiki content as a list of StyledLines</param> ///// <param name="output">Output object to which output is sent</param> ///// <param name="namespaceManager">The ContentProviderChain that contains the wiki string text</param> ///// <param name="maker">A link maker </param> ///// <param name="external">External wiki map</param> ///// <param name="headingLevelBase">Relative heading level</param> ///// //Formatter(QualifiedTopicRevision topic, IList source, WikiOutput output, NamespaceManager namespaceManager, // LinkMaker maker, ExternalReferencesMap external, int headingLevelBase) //{ // _topic = topic; // _source = source; // _output = output; // _linkMaker = maker; // NamespaceManager = namespaceManager; // _externalWikiMap = external; // _headingLevelBase = headingLevelBase; //} public ParserEngine(Federation fed) { Initialize(); if ((bool)fed.Application["DisableNewParser"]) { _engine = this; } else { if (fed.Application.ExecutionEnvironment == ExecutionEnvironment.Production) { _appPath = fed.Application.ResolveRelativePath("admin"); } else { _appPath = System.Environment.CurrentDirectory; _appPath = System.IO.Path.Combine(_appPath, @"..\..\..\FlexWiki.Web\admin"); } _fed = fed; Regex.CacheSize = 250; _context = new ParserContext("WikiText", this, false); //_xslt = new XslCompiledTransform(true); //debug enabled for stylesheet during development _xslt = new XslCompiledTransform(); _xslt.Load(XsltPath); _processBehaviorToText = false; } }
public ParserRule(string womObject, string pattern, string end, string jump, string optimization, string[] elements, ParserContext ruleContext, ParserContext context) { _parentContext = context; if (!String.IsNullOrEmpty(womObject)) { _womElement = womObject; } else { _womElement = context.WomElement; } _pattern = pattern; _end = end; _jump = jump; _optimization = optimization; _elements = elements; if (!String.IsNullOrEmpty(_jump)) { string filename; switch (_jump) { case "wikiTalkMultiline": case "womMultilineCode": filename = context.ParserApplication.GrammarMultiLinePath; break; case "womIncludeTopicName": filename = context.ParserApplication.GrammarIncludeTopicPath; break; case "womCell": case "womMultilineCell": filename = context.ParserApplication.GrammarWomCellPath; break; case "womTableStyle": filename = context.ParserApplication.GrammarWomTableStylePath; break; case "womStyledCode": filename = context.ParserApplication.GrammarWomStyledCodePath; break; case "womWikiStyledText": case "womStrongText": case "womEmbeddedHeaderText": filename = context.ParserApplication.GrammarWomStyledTextPath; break; default: filename = context.ParserApplication.GrammarWomTextPath; break; } _context = new ParserContext(_jump, context.ParserApplication, this, filename); } else if (!String.IsNullOrEmpty(_end)) { _context = new ParserContext("", context.ParserApplication, this); } else { //origina javascript read: //this.context = def.context || context; if (ruleContext != null) { _context = ruleContext; } else { _context = context; } } }