コード例 #1
0
ファイル: Formatter.cs プロジェクト: nuxleus/flexwikicore
        /// <summary>
        /// Answer the formatted text for a given topic, formatted using a given OutputFormat and possibly showing diffs
        /// with a specified revision
        /// </summary>
        /// <param name="topic">The topic</param>
        /// <param name="format">What format</param>
        /// <param name="showDiffs">true to show diffs</param>
        /// <param name="accumulator">composite cache rule in which to accumulate cache rules (ignored for diffs)</param>
        /// <returns></returns>
        public static string FormattedTopicWithSpecificDiffs(QualifiedTopicRevision topic, OutputFormat format, QualifiedTopicRevision diffWithThisVersion, Federation aFederation, LinkMaker lm)
        {
            // Setup a special link maker that knows what to make the edit links return to
            LinkMaker linker = lm.Clone();
            linker.ReturnToTopicForEditLinks = topic;
            NamespaceManager relativeToBase = aFederation.NamespaceManagerForNamespace(topic.Namespace);

            WikiOutput output = WikiOutput.ForFormat(format, null);
            if (diffWithThisVersion != null)
            {
                ArrayList styledLines = new ArrayList();
                IList leftLines;
                IList rightLines;
                using (TextReader srLeft = relativeToBase.TextReaderForTopic(topic.AsUnqualifiedTopicRevision()))
                {
                    leftLines = MergeBehaviorLines(srLeft.ReadToEnd().Replace("\r", "").Split('\n'));
                }
                using (TextReader srRight = relativeToBase.TextReaderForTopic(diffWithThisVersion.AsUnqualifiedTopicRevision()))
                {
                    rightLines = MergeBehaviorLines(srRight.ReadToEnd().Replace("\r", "").Split('\n'));
                }
                IEnumerable diffs = Diff.Compare(leftLines, rightLines);
                foreach (LineData ld in diffs)
                {
                    LineStyle style = LineStyle.Unchanged;
                    switch (ld.Type)
                    {
                        case LineType.Common:
                            style = LineStyle.Unchanged;
                            break;

                        case LineType.LeftOnly:
                            style = LineStyle.Add;
                            break;

                        case LineType.RightOnly:
                            style = LineStyle.Delete;
                            break;
                    }
                    styledLines.Add(new StyledLine(ld.Text, style));
                }
                Format(topic, styledLines, output, relativeToBase, linker, relativeToBase.ExternalReferences, 0);
            }
            else
            {
                using (TextReader sr = relativeToBase.TextReaderForTopic(topic.AsUnqualifiedTopicRevision()))
                {
                    Format(topic, sr.ReadToEnd(), output, relativeToBase, linker, relativeToBase.ExternalReferences, 0);
                }
            }

            return output.ToString();
        }
コード例 #2
0
ファイル: ParserEngine.cs プロジェクト: nuxleus/flexwikicore
        private string wikiIncludedTopic(Match match)
        {
            string replacement = match.ToString();
            string linestart = match.Groups["LineStart"].Value;

            if (!preBehavior.IsMatch(linestart))
            {
                string topic = match.Groups["IncludedTopic"].Value;
                TopicRevision topicRevision = new TopicRevision(topic);
                int size = 0;

                if (_mgr.TopicExists(topicRevision, ImportPolicy.IncludeImports))
                {
                    string ns = _mgr.UnambiguousTopicNameFor(topicRevision.LocalName).Namespace;
                    NamespaceManager containingNamespaceManager = _fed.NamespaceManagerForNamespace(ns);
                    QualifiedTopicRevision abs = new QualifiedTopicRevision(topicRevision.LocalName, ns);
                    if (containingNamespaceManager.HasPermission(new UnqualifiedTopicName(abs.LocalName), TopicPermission.Read))
                    {
                        replacement = containingNamespaceManager.Read(abs.LocalName.TrimEnd());
                    }
                    _behaviorTopic = abs;
                    string tempsize = _mgr.GetTopicProperty(_behaviorTopic.AsUnqualifiedTopicRevision(), "_ProcessTextSize").LastValue;
                    Int32.TryParse(tempsize, out size);
                    if (size == 0)
                    {
                        size = _chunk;
                    }
                    replacement = findWikiBehavior.Replace(replacement, new MatchEvaluator(wikiBehaviorMatch));
                    replacement = replacement.Replace("        ", "\t");
                    replacement = escape(replacement);
                    if (_processBehaviorToText)
                    {
                        WomDocument xmldoc = ProcessText(replacement, abs, _mgr, true, size);
                        replacement = xmldoc.ParsedDocument;
                    }
                    else
                    {
                        _processBehaviorToText = true;
                    }
                    _behaviorTopic = null;
                }
            }
            return replacement + "\r\n";
        }
コード例 #3
0
ファイル: ParserEngine.cs プロジェクト: nuxleus/flexwikicore
        //this is where fragments are prepped for parsing
        public WomDocument FormatTextFragment(string wikiInput, QualifiedTopicRevision topic, NamespaceManager mgr, bool fragment, int sizeIn)
        {
            WomDocument xmldoc = new WomDocument(null);
            string wikitext = "";
            _mgr = mgr;
            _topic = topic;
            WomDocument.ResetTableOfContents();
            WomDocument.anchors = new string[25];
            _processBehaviorToText = true;
            _behaviorTopic = topic;

            wikitext = escape(wikiInput);
            int size = 0;
            bool done = false;
            while (!done)
            {
                try
                {
                    string tempsize = _mgr.GetTopicProperty(topic.AsUnqualifiedTopicRevision(), "_ProcessTextSize").LastValue;
                    Int32.TryParse(tempsize, out size);
                    if (size == 0)
                    {
                        size = sizeIn;
                    }
                    xmldoc = ProcessText(wikitext, topic, _mgr, fragment, size);
                    //string womdoc = xmldoc.ParsedDocument;
                    //string firstPass = findWikiBehavior.Replace(womdoc, new MatchEvaluator(wikiBehaviorMatch));
                    //xmldoc.ParsedDocument = findWikiBehavior.Replace(firstPass, new MatchEvaluator(wikiBehaviorMatch));
                    while (findWikiBehavior.IsMatch(xmldoc.ParsedDocument))
                    {
                        xmldoc.ParsedDocument = findWikiBehavior.Replace(xmldoc.ParsedDocument, new MatchEvaluator(wikiBehaviorMatch));
                    }

                    _behaviorTopic = null;

                    if (findIncludedTopic.IsMatch(xmldoc.ParsedDocument))
                    {
                        string included = xmldoc.ParsedDocument;
                        included = findIncludedTopic.Replace(included, new MatchEvaluator(wikiIncludedTopic));
                        xmldoc.ParsedDocument = included;
                    }
                    done = true;
                    //interpreted = xmldoc.ParsedDocument;
                    //xmldoc = null;
                }
                catch (XmlException ex)
                {
                    _mgr.SetProcessTextSize(topic.AsUnqualifiedTopicRevision(), size * (chunkcnt + 1));
                    string error = "<Error>" + ex.ToString() + "</Error>";
                    xmldoc.ParsedDocument = error;
                }
            }
            return xmldoc;
        }
コード例 #4
0
ファイル: ParserEngine.cs プロジェクト: nuxleus/flexwikicore
        //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;
        }
コード例 #5
0
ファイル: ParserEngine.cs プロジェクト: nuxleus/flexwikicore
        public string FormattedTopic(QualifiedTopicRevision topic, OutputFormat fmt)
        {
            //initial version does not handle diffs
            string wikitext = "";
            string interpreted = "";
            _mgr = _fed.NamespaceManagerForNamespace(topic.Namespace);
            _topic = topic;
            WomDocument.ResetTableOfContents();
            WomDocument.anchors = new string[25];
            _processBehaviorToText = true;
            _behaviorTopic = topic;

            //Normally get data from the cache, but when debugging Womdocument need to avoid using cached data
            string wom = _mgr.GetTopicProperty(topic.AsUnqualifiedTopicRevision(), "_Wom").LastValue;
            //string wom = "";

            if (!String.IsNullOrEmpty(wom))
            {
                WomDocument xmldoc = new WomDocument(null);
                wom = findWikiBehavior.Replace(wom, new MatchEvaluator(wikiBehaviorMatch));
                xmldoc.ParsedDocument = findWikiBehavior.Replace(wom, new MatchEvaluator(wikiBehaviorMatch));

                if (findIncludedTopic.IsMatch(xmldoc.ParsedDocument))
                {
                    string included = xmldoc.ParsedDocument;
                    included = findIncludedTopic.Replace(included, new MatchEvaluator(wikiIncludedTopic));
                    xmldoc.ParsedDocument = included;
                }

                interpreted = xmldoc.ParsedDocument;
                xmldoc = null;
            }
            else
            {
                using (TextReader sr = _mgr.TextReaderForTopic(topic.AsUnqualifiedTopicRevision()))
                {
                    wikitext = sr.ReadToEnd() + "\r\n";
                }
                wikitext = escape(wikitext);
                int size = 0;
                while (String.IsNullOrEmpty(interpreted))
                {
                    try
                    {
                        string tempsize = _mgr.GetTopicProperty(topic.AsUnqualifiedTopicRevision(), "_ProcessTextSize").LastValue;
                        Int32.TryParse(tempsize, out size);
                        if (size == 0)
                        {
                            size = _chunk;
                        }
                        WomDocument xmldoc = ProcessText(wikitext, topic, _mgr, false, size);
                        //string womdoc = xmldoc.ParsedDocument;
                        _mgr.SetWomCache(topic.AsUnqualifiedTopicRevision(), xmldoc.ParsedDocument);
                        //string firstPass = findWikiBehavior.Replace(womdoc, new MatchEvaluator(wikiBehaviorMatch));
                        //xmldoc.ParsedDocument = findWikiBehavior.Replace(firstPass, new MatchEvaluator(wikiBehaviorMatch));
                        while (findWikiBehavior.IsMatch(xmldoc.ParsedDocument))
                        {
                            xmldoc.ParsedDocument = findWikiBehavior.Replace(xmldoc.ParsedDocument, new MatchEvaluator(wikiBehaviorMatch));
                        }

                        _behaviorTopic = null;

                        if (findIncludedTopic.IsMatch(xmldoc.ParsedDocument))
                        {
                            string included = xmldoc.ParsedDocument;
                            included = findIncludedTopic.Replace(included, new MatchEvaluator(wikiIncludedTopic));
                            xmldoc.ParsedDocument = included;
                        }

                        interpreted = xmldoc.ParsedDocument;
                        xmldoc = null;
                    }
                    catch (XmlException ex)
                    {
                        _mgr.SetProcessTextSize(topic.AsUnqualifiedTopicRevision(), size * (chunkcnt + 1));
                        string error = ex.ToString();
                    }
                }
            }
            _processBehaviorToText = false;
            return interpreted;
        }