コード例 #1
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 public string LinkToTopic(TopicRevision topic, bool showDiffs, NameValueCollection extraQueryParms)
 {
     return TopicLink(topic.DottedNameWithVersion, showDiffs, extraQueryParms);
 }
コード例 #2
0
 public static DuplicateTopicException ForTopic(TopicRevision tn)
 {
     DuplicateTopicException answer = new DuplicateTopicException("Duplicate topic: " + tn.ToString());
     answer.Topic = tn;
     return answer;
 }
コード例 #3
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 public string LinkToTopic(TopicRevision topic, bool showDiffs)
 {
     return TopicLink(topic.DottedNameWithVersion, showDiffs, null);
 }
コード例 #4
0
ファイル: Formatter.cs プロジェクト: nuxleus/flexwikicore
 private string IncludedTopic(TopicRevision topic, int headingLevelBase)
 {
     // TODO: how do we identify specific versions? [maybe this just works now? since versionids are a formal part of a wikiname???]
     // TODO: how do we show diffs?
     string ns = NamespaceManager.UnambiguousTopicNameFor(topic.LocalName).Namespace;
     NamespaceManager containingNamespaceManager = Federation.NamespaceManagerForNamespace(ns);
     QualifiedTopicRevision abs = new QualifiedTopicRevision(topic.LocalName, ns);
     string content = "";
     if (containingNamespaceManager.HasPermission(new UnqualifiedTopicName(abs.LocalName), TopicPermission.Read))
     {
         content = containingNamespaceManager.Read(abs.LocalName).TrimEnd();
     }
     WikiOutput output = WikiOutput.ForFormat(_output.Format, Output);
     Formatter.Format(abs, content, output, NamespaceManager, LinkMaker(), _externalWikiMap, headingLevelBase);
     return output.ToString().Trim();
 }
コード例 #5
0
ファイル: Formatter.cs プロジェクト: nuxleus/flexwikicore
        private string ProcessWikiLinks(string str)
        {
            MatchCollection matches = wikiURIRegex.Matches(str);
            ArrayList processed = new ArrayList();
            string answer = str;
            foreach (Match m in matches)
            {
                string uriString = m.Groups["uri"].ToString();
                if (processed.Contains(uriString))
                {
                    continue;   // skip dup
                }
                processed.Add(uriString);

                // Get  the pieces
                string authority = m.Groups["authority"].ToString();
                string path = m.Groups["path"].ToString();
                string fragment = m.Groups["fragment"].ToString();

                // OK, we have a good URI -- let's decide if it's:
                // wiki://topic
                //		Case 1 - Link to the topic
                //	wiki://topic/rez…
                //		Case 2 - Read the topic, rewrite using the LibraryURL
                // wiki://topic/#propertyName
                //		Case 3 - Inline the propertyName value

                if (path == "" || path == "/")
                {
                    // We've got only a topic
                    TopicRevision topicName = new TopicRevision(authority);
                    // See if we want the whole topic or just a propertyName (via a fragment)
                    if (fragment != "")
                    {
                        // Case 3 -- Ask for a propertyName
                        TopicName abs = null;
                        bool ambig = false;
                        try
                        {
                            abs = NamespaceManager.UnambiguousTopicNameFor(topicName.LocalName);
                        }
                        catch (TopicIsAmbiguousException)
                        {
                            ambig = true;
                        }
                        string replacement;
                        if (abs != null)
                        {
                            // Got a unique URI it!
                            replacement = Federation.GetTopicPropertyValue(abs, fragment);
                        }
                        else
                        {
                            if (ambig)
                                replacement = "(ambiguous topic name: " + topicName + ")";
                            else
                                replacement = "(unknown topic name: " + topicName + ")";
                        }
                        answer = answer.Replace(uriString, replacement);
                    }
                    else
                    {
                        // Case 1 - a whole topic
                        answer = LinkWikiNames(authority);
                    }
                }
                else
                {
                    // Case 2 - We're being asked for a resource in a resource library
                    TopicName abs = null;
                    TopicRevision topicName = new TopicRevision(authority);
                    bool ambig = false;
                    try
                    {
                        abs = NamespaceManager.UnambiguousTopicNameFor(topicName.LocalName);
                    }
                    catch (TopicIsAmbiguousException)
                    {
                        ambig = true;
                    }
                    string replacement;
                    if (abs != null)
                    {
                        // Got a unique URI it!
                        string uriForLibrary = Federation.GetTopicPropertyValue(abs, "URI");
                        string pathWithoutPrefixSlash = path.TrimStart('/');
                        string resourceURI = uriForLibrary.Replace("$$$", pathWithoutPrefixSlash);
                        replacement = LinkHyperLinks(resourceURI);
                    }
                    else
                    {
                        if (ambig)
                            replacement = "(ambiguous library topic name: " + topicName + ")";
                        else
                            replacement = "(unknown library topic name: " + topicName + ")";
                    }

                    answer = answer.Replace(uriString, replacement);
                }
            }
            return answer;
        }
コード例 #6
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 public string LinkToLogoff(TopicRevision topic)
 {
     return LinkToLogoff(topic);
 }
コード例 #7
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 public string LinkToRestore(TopicRevision topic)
 {
     return RestoreLink(topic.DottedNameWithVersion);
 }
コード例 #8
0
ファイル: NamespaceManager.cs プロジェクト: nuxleus/flexwiki
        /// <summary>
        /// Rename references (in a given topic) from one topic to a new name 
        /// </summary>
        /// <param name="topicToLookIn"></param>
        /// <param name="oldName"></param>
        /// <param name="newName"></param>
        /// <returns></returns>
        private bool RenameTopicReferences(string topicToLookIn, string oldName, string newName, string author)
        {
            //CA I'm not thrilled about using this older implementation - it seems 
            //CA like this functionality should come out of the new parsing provider
            //CA somehow, but there's already enough in the rearchitecture without goofing
            //CA with that as well...
            string current = Read(topicToLookIn);
            MatchCollection wikiNames = Formatter.extractWikiNames.Matches(current);
            ArrayList processed = new ArrayList();
            bool any = false;
            TopicRevision newTopicRevision = new QualifiedTopicRevision(newName, this.Namespace);
            TopicName newTopicName = new TopicName(newTopicRevision.LocalName, newTopicRevision.Namespace); 
            foreach (Match m in wikiNames)
            {
                string each = m.Groups["topic"].ToString();
                if (processed.Contains(each))
                {
                    continue;   // skip dup	
                }
                processed.Add(each);

                TopicRevision relName = new TopicRevision(TopicParser.StripTopicNameEscapes(each));

                // See if this is the old name.  The only way it can be is if it's unqualified or if it's qualified with the current namespace.

                bool hit = (relName.LocalName == oldName) && (relName.Namespace == null || relName.Namespace == this.Namespace);
                if (!hit)
                {
                    continue;
                }

                // Now see if we got any hits or not
                string rep = Formatter.s_beforeWikiName + "(" + Formatter.RegexEscapeTopic(each) + ")" + Formatter.s_afterWikiName;
                // if the reference was fully qualified, retain that form in the new reference
                string replacementName = each.IndexOf(".") > -1 ? newTopicName.DottedName : newTopicName.LocalName;
                current = Regex.Replace(current, rep, "${before}" + replacementName + "${after}");
                any = true;
            }

            if (any)
            {
                WriteTopicAndNewVersion(topicToLookIn, current, author);
            }

            return any;
        }///// <summary>
コード例 #9
0
ファイル: Federation.cs プロジェクト: nuxleus/flexwiki
        public NamespaceManager NamespaceManagerForTopic(TopicRevision topic, string nsRelativeTo)
        {
            if (topic.IsQualified)
            {
                return NamespaceManagerForNamespace(topic.Namespace); 
            }

            return NamespaceManagerForNamespace(nsRelativeTo); 
        }
コード例 #10
0
ファイル: ClassicBehaviors.cs プロジェクト: nuxleus/flexwiki
 public string Property(ExecutionContext ctx, string topic, string property)
 {
     TopicName abs = null;
     bool ambig = false;
     string answer = null;
     try
     {
         NamespaceManager namespaceManager = ctx.CurrentNamespaceManager;
         if (namespaceManager == null)
             namespaceManager = ctx.CurrentFederation.DefaultNamespaceManager;
         TopicRevision rel = new TopicRevision(topic);
         abs = namespaceManager.UnambiguousTopicNameFor(rel.LocalName);
     }
     catch (TopicIsAmbiguousException)
     {
         ambig = true;
     }
     if (abs != null)
     {
         // Got a unique one!
         answer = ctx.CurrentFederation.GetTopicPropertyValue(abs, property);
     }
     else
     {
         if (ambig)
             throw new ArgumentException("Ambiguous topic name: " + topic);
         else
             throw new ArgumentException("Unknown topic name: " + topic);
     }
     return answer;
 }
コード例 #11
0
ファイル: NamespaceManager.cs プロジェクト: nuxleus/flexwiki
 /// <summary>
 /// Answer true if the given topic exists in this namespace or in an imported namespace (if it's relative), or in the given namespace (if it's qualified)
 /// </summary>
 /// <param name="topic">The topic to check for</param>
 /// <returns>true if the topic exists</returns>
 /// <remarks>importPolicy is ignored if the topic name is qualified.</remarks>
 public bool TopicExists(TopicRevision topic, ImportPolicy importPolicy)
 {
     if (topic.IsQualified)
     {
         return Federation.TopicExists(new QualifiedTopicRevision(topic.LocalName, topic.Namespace));
     }
     else
     {
         return TopicExists(topic.LocalName, importPolicy);
     }
 }
コード例 #12
0
 internal static FlexWikiException VersionDoesNotExist(TopicRevision revision)
 {
     return VersionDoesNotExist(revision.Name, revision.Version);
 }
コード例 #13
0
 public bool TopicIsReadOnly(TopicRevision topic)
 {
     if (topic.IsQualified)
     {
         return Federation.TopicIsReadOnly(new QualifiedTopicRevision(topic.LocalName, topic.Namespace));
     }
     else
     {
         return TopicIsReadOnly(topic.LocalName);
     }
 }
コード例 #14
0
ファイル: FileSystemStore.cs プロジェクト: nuxleus/flexwiki
 private static string MakeTopicFilename(TopicRevision topic)
 {
     if (topic.Version == null)
     {
         return topic.LocalName + ".wiki";
     }
     else
     {
         return topic.LocalName + "(" + topic.Version + ").awiki";
     }
 }
コード例 #15
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 private string TopicLink(string top, bool showDiffs, NameValueCollection extraQueryParms)
 {
     StringBuilder builder = new StringBuilder();
     TopicRevision topic = new TopicRevision(top);
     builder.Append(SiteURL());
     builder.Append("default.aspx/");
     if (topic.Namespace != null && topic.Namespace != "")
         builder.Append(HttpUtility.UrlEncode(topic.Namespace) + "/");
     builder.Append(topic.LocalName);
     if (topic.Version != null)
         builder.Append("(" + HttpUtility.UrlEncode(topic.Version) + ")");
     builder.Append(".html");		// hard coded for now -- later we'll be cooler!
     StringBuilder query = new StringBuilder();
     if (showDiffs)
         query.Append("diff=y");
     if (extraQueryParms != null)
     {
         foreach (string each in extraQueryParms)
         {
             if (query.Length != 0)
                 query.Append("&");
             query.Append(each + "=" + HttpUtility.UrlEncode((string) (extraQueryParms[each])));
         }
     }
     if (query.Length != 0)
         builder.Append("?" + query.ToString());
     return builder.ToString();
 }
コード例 #16
0
ファイル: Federation.cs プロジェクト: nuxleus/flexwiki
        /// <summary>
        /// Answer the full name of the topic (qualified with namespace) if it exists.  
        /// If it doesn't exist at all, answer null.
        /// If it does, but it's ambiguous, then throw TopicIsAmbiguousException
        /// </summary>
        /// <param name="topic"></param>
        /// <returns>Full name or null if it doesn't exist (by throw TopicIsAmbiguousException if it's ambiguous)</returns>
        public QualifiedTopicRevision UnambiguousTopicNameFor(TopicRevision topic, string nsRelativeTo)
        {
            NamespaceManager manager = NamespaceManagerForTopic(topic, nsRelativeTo);

            if (manager == null)
            {
                return null;                     
            }

            NamespaceCollection namespaces = manager.TopicNamespaces(topic.LocalName);
            if (namespaces.Count == 0)
            {
                return null;
            }
            if (namespaces.Count > 1)
            {
                throw TopicIsAmbiguousException.ForTopic(topic);
            }
            return new QualifiedTopicRevision(topic.LocalName, (string)namespaces[0]);
        }
コード例 #17
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 public string LinkToLogin(TopicRevision topic)
 {
     return LinkToLogin(topic.DottedNameWithVersion);
 }
コード例 #18
0
ファイル: Federation.cs プロジェクト: nuxleus/flexwiki
        /// <summary>
        /// Answer a list of the wikitext components (IBELObjects) of the given border.  If nothing specifies any border; answer the system default
        /// </summary>
        /// <param name="name"></param>
        /// <param name="border"></param>
        /// <param name="rule"></param> 
        /// <returns></returns>
        private IEnumerable BorderText(QualifiedTopicRevision name, Border border)
        {
            ArrayList answer = new ArrayList();
            NamespaceManager namespaceManager;
            string bordersTopicsProperty = "Borders";

            ArrayList borderTopics = new ArrayList();


            // Start with whatever the namespace defines
            if (Borders != null)
            {
                foreach (string at in ParseListPropertyValue(Borders))
                {
                    QualifiedTopicRevision abs = new QualifiedTopicRevision(at);
                    namespaceManager = NamespaceManagerForTopic(abs);
                    if (abs == null || namespaceManager == null)
                    {
                        throw new Exception("Unknown namespace listed in border topic (" + at + ") listed in federation configuration Borders property.");
                    }
                    borderTopics.Add(at);
                }
            }


            // If the namespace, specifies border topics, get them
            namespaceManager = NamespaceManagerForTopic(name);
            if (namespaceManager != null)
            {
                borderTopics.AddRange(GetTopicListPropertyValue(
                    new QualifiedTopicRevision(namespaceManager.DefinitionTopicName), 
                    bordersTopicsProperty));
            }

            // If there are no border topics specified for the federation or the namespace, add the default (_NormalBorders from the local namespace)
            if (borderTopics.Count == 0)
            {
                borderTopics.Add("_NormalBorders");
            }


            // Finally, any border elements form the topic itself (skip the def topic so we don't get double borders!)
            if (namespaceManager == null || namespaceManager.DefinitionTopicName.ToString() != name.ToString())
            {
                borderTopics.AddRange(GetTopicListPropertyValue(name, bordersTopicsProperty));
            }


            Set done = new Set();
            foreach (string borderTopicName in borderTopics)
            {
                // Figure out what the qualified topic name is that we're going to get this topic from
                TopicRevision rel = new TopicRevision(borderTopicName);
                if (!rel.IsQualified)
                {
                    rel = new TopicRevision(borderTopicName, name.Namespace);
                }
                QualifiedTopicRevision abs = new QualifiedTopicRevision(rel.LocalName, rel.Namespace);
                if (done.Contains(abs))
                {
                    continue;
                }
                done.Add(abs);
                IBELObject s = BorderPropertyFromTopic(name, abs, border);
                if (s != null)
                {
                    answer.Add(s);
                }
            }

            return answer;
        }
コード例 #19
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 public string LinkToPrintView(TopicRevision topic)
 {
     return PrintLink(topic.DottedNameWithVersion);
 }
コード例 #20
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";
        }
コード例 #21
0
 public static TopicIsAmbiguousException ForTopic(TopicRevision topic)
 {
     TopicIsAmbiguousException answer = new TopicIsAmbiguousException("Topic is ambiguous: " + topic.ToString());
     answer.Topic = topic;
     return answer;
 }
コード例 #22
0
ファイル: TopicParser.cs プロジェクト: nuxleus/flexwiki
        private static TopicRevisionCollection ParseTopicLinks(string text)
        {
            TopicRevisionCollection referencedTopics = new TopicRevisionCollection();

            // TODO: Move Formatter functionality to TopicParser
            MatchCollection wikiNames = Formatter.extractWikiNames.Matches(text);

            List<string> processed = new List<string>();

            foreach (Match m in wikiNames)
            {
                string each = m.Groups["topic"].ToString();
                if (processed.Contains(each))
                {
                    continue;   // skip duplicates
                }

                processed.Add(each);

                TopicRevision referencedTopic = new TopicRevision(StripTopicNameEscapes(each));
                referencedTopics.Add(referencedTopic);
            }

            return referencedTopics;
        }
コード例 #23
0
ファイル: Formatter.cs プロジェクト: nuxleus/flexwikicore
        private string LinkWikiNames(string input)
        {
            StringBuilder answer = new StringBuilder();

            string str = input;
            ArrayList processed = new ArrayList();
            while (str.Length > 0)
            {
                Match m = extractWikiLinks.Match(str);
                if (!m.Success)
                    break;
                string each = m.Groups["topic"].ToString();
                string before = m.Groups["before"].ToString();
                string after = m.Groups["after"].ToString();
                string relabel = m.Groups["relabel"].ToString();
                string anchor = m.Groups["anchor"].ToString();

                TopicName relName = new TopicName(TopicParser.StripTopicNameEscapes(each));

                // Ignore apparent links to non-existent namespaces.
                if ((null == relName.Namespace) || (null != Federation.NamespaceManagerForNamespace(relName.Namespace)))
                {
                    // Build a list of all the possible qualified names for this topic
                    QualifiedTopicNameCollection qualifiedNames = new QualifiedTopicNameCollection();
                    // Start with the singulars in the various reachable namespaces, then add the plurals
                    qualifiedNames.AddRange(Federation.AllQualifiedTopicNamesThatExist(relName, NamespaceManager.Namespace, AlternatesPolicy.IncludeAlternates));

                    // Now see if we got any hits or not
                    string rep = beforeOrRelabel + "(" + RegexEscapeTopic(each) + ")" + s_afterWikiName;
                    TopicRevision appearedAs = new TopicRevision(each);  // in case it was a plural form, be sure to show it as it appeared
                    string displayname = TopicParser.StripTopicNameEscapes((NamespaceManager.DisplaySpacesInWikiLinks ? appearedAs.FormattedName : appearedAs.LocalName));
                    if (relabel.Length > 0)
                    {
                        displayname = relabel;
                    }

                    if (qualifiedNames.Count == 0)
                    {
                        if (!IsUnbracketedOneWordName(each))
                        {
                            // It doesn't exist, so give the option to create it
                            TopicName abs = relName.ResolveRelativeTo(NamespaceManager.Namespace);
                            //XHTML bug when str is enclosed in an wrapping anchor - property with undefined WikiTopic
                            str = ReplaceMatch(answer, str, m, before + "<a title=\"Click here to create this topic\" class=\"create\" href=\"" + LinkMaker().LinkToEditTopic(abs) + "\">" + displayname + "</a>" + after);
                        }
                        else
                        {
                            str = ReplaceMatch(answer, str, m, m.Value);
                        }
                    }
                    else
                    {
                        // We got hits, let's add links

                        if (qualifiedNames.Count == 1)
                        {
                            // The simple case is that there's only one link to point to, so we output just a normal link
                            TopicName abs = qualifiedNames[0];
                            string tip = TipForTopic(abs);
                            string tipid = null;
                            string tipHTML = null;
                            bool defaultTip = tip == null;
                            if (defaultTip)
                            {
                                tip = "Click to read this topic";
                            }
                            tipid = NewUniqueIdentifier();
                            tipHTML = Formatter.EscapeHTML(tip);
                            if (defaultTip)
                            {
                                tipHTML = "<span class=\"DefaultTopicTipText\">" + tipHTML + "</span>";
                            }
                            // No point in trying to show author and modification time if we don't have
                            // read permission on the link target: it'll just throw an exception if we
                            // try to get them.
                            if (Federation.HasPermission(new QualifiedTopicRevision(abs.DottedName), TopicPermission.Read))
                            {
                                tipHTML += "<div class=\"TopicTipStats\">" + Federation.GetTopicLastModificationTime(abs).ToString();
                                string lastAuthor = Federation.GetTopicLastModifiedBy(abs);
                                if (string.IsNullOrEmpty(lastAuthor))
                                {
                                    lastAuthor = "author unknown";
                                }
                                tipHTML += " - " + lastAuthor + "</div>";
                            }
                            tipHTML = "<div id=\"" + tipid + "\" style=\"display: none\">" + tipHTML + "</div>";
                            Output.AddToFooter(tipHTML);
                            string replacement = "<a ";
                            if (tip != null)
                            {
                                replacement += "onmouseover=\"TopicTipOn(this, '" + tipid + "', event);\" onmouseout=\"TopicTipOff();\" ";
                            }
                            replacement += "href=\"" + LinkMaker().LinkToTopic(abs.DottedName);
                            if (anchor.Length > 0)
                            {
                                replacement += "#" + anchor;
                                if (0 == relabel.Length)
                                {
                                    displayname += "#" + anchor;
                                }
                            }
                            replacement += "\">" + displayname + "</a>";
                            str = ReplaceMatch(answer, str, m, before + replacement + after);
                        }
                        else
                        {
                            // There's more than one; we need to generate a dynamic menu
                            string clickEvent;
                            clickEvent = "onclick=\"javascript:LinkMenu(new Array(";
                            bool first = true;
                            foreach (TopicName eachAbs in qualifiedNames)
                            {
                                if (!first)
                                    clickEvent += ", ";
                                first = false;
                                clickEvent += "new Array('" + eachAbs + "', '" + LinkMaker().LinkToTopic(eachAbs) + "')";
                            }
                            clickEvent += "), event);\"";

                            str = ReplaceMatch(answer, str, m, before + "<a title=\"Different versions of this topic exist.  Click to pick one.\" " + clickEvent + ">" + displayname + "</a>" + after);
                        }
                    }
                }
                else
                {
                    str = ReplaceMatch(answer, str, m, before + relName.DottedName + after);
                }
            }

            // Add on whatever's not yet been consumed
            answer.Append(str);
            return answer.ToString();
        }
コード例 #24
0
ファイル: LinkMaker.cs プロジェクト: nuxleus/flexwiki
 public string LinkToTopic(TopicRevision topic)
 {
     return LinkToTopic(topic, false);
 }
コード例 #25
0
ファイル: Formatter.cs プロジェクト: nuxleus/flexwikicore
        /// <summary>
        /// Main formatting function.  The process of formatting the input to the output starts here.
        /// </summary>
        public void Format()
        {
            if (Federation.GetPerformanceCounter(PerformanceCounterNames.TopicFormat) != null)
            {
                Federation.GetPerformanceCounter(PerformanceCounterNames.TopicFormat).Increment();
            }

            for(int i=0;i<35;i++) indiceCount[i] = 1 ;
            CurrentState = new NeutralState(this);
            _currentLineIndex = 0;
            bool inMultilineProperty = false;
            bool currentMultilinePropertyIsHidden = false;
            string multiLinePropertyDelim = null;
            bool inPreBlock = false;
            bool inExtendedPreBlock = false;
            string preBlockKey = null;
            bool resetCount=false ;
            bool resetNextCount=false ;
            int thisNest = 0 ;

            _output.Begin();

            for (int lineNumber = 0; lineNumber < _source.Count; lineNumber++)
            {
                StyledLine eachLine = (StyledLine) (_source[lineNumber]);
                string each = eachLine.Text;
                _output.Style = eachLine.Style;

                each = StripHTMLSpecialCharacters(each);

                if (inPreBlock)
                {
                    if ((each.StartsWith("}+") || each.StartsWith("}@")) && each.Substring(2).Trim() == preBlockKey)
                    {
                        Ensure(typeof(NeutralState),0,false,false);
                        inPreBlock = false;
                        inExtendedPreBlock = false;
                        preBlockKey = null;
                    }
                    else
                    {
                        if (false == currentMultilinePropertyIsHidden)
                        {
                            // each = each.Replace("\t", " 	");
                            each = each.Replace("\t","        ");
                            if (inExtendedPreBlock)
                            {
                                // Ensure(CurrentState.GetType(),0,false);
                                each = ProcessLineElements(each);
                            }
                            _output.Write(each);
                            _output.WriteEndLine();
                        }
                        _currentLineIndex++;
                    }
                    continue;
                }
                else if (!inMultilineProperty && (each.StartsWith("{+") || each.StartsWith("{@")))
                {
                    Ensure(typeof(PreState),0,false,false);
                    inPreBlock = true;
                    inExtendedPreBlock = each.StartsWith("{+");
                    preBlockKey = each.Substring(2).Trim();
                    continue;
                }

                // Make all the 8-space sequences into tabs
                each = Regex.Replace(each, " {8}", "\t");

                // See if this is the first line of a multiline propertyName.
                if (!inMultilineProperty && TopicParser.MultilinePropertyRegex.IsMatch(each))
                {
                    // OK, here we go -- time to output the header
                    Match m = TopicParser.MultilinePropertyRegex.Match(each);
                    string name = m.Groups["name"].Value;
                    string val = m.Groups["val"].Value;
                    string leader = m.Groups["leader"].Value;
                    string delim = m.Groups["delim"].Value;
                    multiLinePropertyDelim = TopicParser.ClosingDelimiterForOpeningMultilinePropertyDelimiter(delim);
                    currentMultilinePropertyIsHidden = leader == ":";

                    if (currentMultilinePropertyIsHidden) // just write the anchor for hidden page properties
                    {
                        _output.WriteOpenAnchor(name);
                        _output.WriteCloseAnchor();
                        _output.WriteLine("");
                    }
                    else
                    {
                        // Ensure(CurrentState.GetType(),0,false);
                        // Don't bother showing out hidden page properties
                        val = val.Trim();

                        // Do the normal processing
                        name = StripHTMLSpecialCharacters(name);
                        string linkedName = LinkWikiNames(name);

                        val = StripHTMLSpecialCharacters(val);
                        val = ProcessLineElements(val);

                        _output.WriteOpenProperty(linkedName);
                        _output.WriteOpenAnchor(name);
                        if (TopicParser.IsBehaviorPropertyDelimiter(delim))
                        {
                            _output.Write(delim);
                        }
                        _output.Write(val);
                    }
                    inMultilineProperty = true;
                    continue;
                }

                if (inMultilineProperty)
                {
                    if (each.StartsWith(multiLinePropertyDelim))
                    {
                        // We're done!
                        if (!currentMultilinePropertyIsHidden)
                        {
                            if (TopicParser.IsBehaviorPropertyDelimiter(multiLinePropertyDelim))
                            {
                                _output.Write(multiLinePropertyDelim);
                            }
                            // Make sure we close off things like tables before we close the propertyName.
                            Ensure(typeof(NeutralState),0,false,false);
                            _output.WriteCloseAnchor();
                            _output.WriteCloseProperty();
                        }
                        inMultilineProperty = false;
                        currentMultilinePropertyIsHidden = false;
                        continue;
                    }

                    // If it's a line for a propertyName behavior, just show it -- don't perform any processing
                    if (TopicParser.IsBehaviorPropertyDelimiter(multiLinePropertyDelim))
                    {
                        if (!currentMultilinePropertyIsHidden)
                        {
                            _output.WriteSingleLine(each);
                        }
                        continue;
                    }
                }

                if (Formatter.StripExternalWikiDef(_externalWikiMap, each))
                    continue;

                // empty line resets everything (except pre and multiline imports )
                if (each.Trim().Length == 0)
                {
                    if (!(CurrentState is PreState) || (CurrentState is PreState && !IsNextLinePre()))
                        Ensure(typeof(NeutralState),0,false,false);
                    _output.WriteEndLine();
                }
                else if ((each.StartsWith("----")) && (false == currentMultilinePropertyIsHidden))
                {
                    Ensure(typeof(NeutralState),0,false,false);
                    _output.WriteRule();
                }
                // insert topic -- {{IncludeSomeTopic}} ?
                else if ((!each.StartsWith(" ") & Regex.IsMatch(each, @"^[\t]*\{\{" + s_wikiName + @"\}\}[\s]*$")) &&
                    (false == currentMultilinePropertyIsHidden))
                {
                    Regex nameGetter = new Regex("(?<topic>" + s_wikiName + ")");
                    string name = nameGetter.Matches(each)[0].Groups["topic"].Value;
                    TopicRevision topicRevision = new TopicRevision(name);

                    // Count the tabs
                    int tabs = 0;
                    string tabber = each;
                    while (tabber.Length > 0 && (tabber.StartsWith("\t")))
                    {
                        tabs++;
                        tabber = tabber.Substring(1);
                    }

                    Ensure(typeof(NeutralState),0,false,false);
                    if (NamespaceManager.TopicExists(topicRevision, ImportPolicy.IncludeImports))
                    {
                        if ((!IsBeyondSafeNestingDepth) && (false == currentMultilinePropertyIsHidden))
                        {
                            _output.Write(IncludedTopic(topicRevision, _headingLevelBase + tabs));
                        }
                    }
                    else
                    {
                        EnsureParaOpen();
                        _output.Write(LinkWikiNames(each));
                        EnsureParaClose();
                    }
                }
                // line begins with a space, it's PRE time!
                else if ((each.StartsWith(" ") || Regex.IsMatch(each, "^[ \t]+[^ \t*1#]")) &&
                    (false == currentMultilinePropertyIsHidden))
                {
                    Ensure(typeof(PreState),0,false,false);
                    _output.Write(Regex.Replace(each, "\t", "        "));
                }

                else
                {
                    // OK, it's likely more complicated

                    // Continue if we're inside a multiline hidden propertyName.
                    if (true == currentMultilinePropertyIsHidden)
                    {
                        continue;
                    }

                    // See if this is a bullet line
                    if (each.StartsWith("\t"))
                    {
                        each = ProcessLineElements(each);
                        // Save the last nesting level
                        // Starts with a tab - might be a list (we'll see)
                        // Count the tabs
                        thisNest = 0;
                        while (each.Length > 0 && (each.StartsWith("\t")))
                        {
                            thisNest++;
                            each = each.Substring(1);
                        }

                        if (each.StartsWith("*"))
                        {
                            each = each.Substring(1);
                            // We're in a list - make sure we've got the right <ul> nesting setup
                            // Could need more or fewer
                            if(CurrentState.GetType().ToString().Equals(typeof(UnorderedListState).ToString()) ||
                               CurrentState.GetType().ToString().Equals(typeof(OrderedListState).ToString()))
                                resetCount = false ;
                            else
                                resetCount = true ;
                            if(resetNextCount)
                            {
                               resetCount = true ;
                               resetNextCount = false ;
                            }
                            Ensure(typeof(UnorderedListState),thisNest,resetCount,false);
                            if ((bool)Federation.Application["RemoveListItemWhitespace"] == false)
                            {
                                _output.WriteListItem(each);
                            }
                            else
                            {
                                _output.WriteListItem(each.Trim());
                            }
                            indiceCount[stateStack.Count-1] = indiceCount[stateStack.Count-1] + 1 ;
                        }
                        else if (each.StartsWith("1."))
                        {
                         	each = each.Substring(2);
                            if(CurrentState.GetType().ToString().Equals(typeof(UnorderedListState).ToString()) ||
                               CurrentState.GetType().ToString().Equals(typeof(OrderedListState).ToString()))
                                resetCount = false ;
                            else
                                resetCount = true ;
                            if(resetNextCount)
                            {
                               resetCount = true ;
                               resetNextCount = false ;
                            }
                         	Ensure(typeof(OrderedListState),thisNest,resetCount,false);                            if ((bool)Federation.Application["RemoveListItemWhitespace"] == false)
                            if ((bool)Federation.Application["RemoveListItemWhitespace"] == false)
                            {
                                _output.WriteListItem(each);
                            }
                            else
                            {
                                _output.WriteListItem(each.Trim());
                            }
                            indiceCount[stateStack.Count-1] = indiceCount[stateStack.Count-1] + 1 ;
                        }
                        else if (each.StartsWith("#^"))
                        {
                            each = each.Substring(2);
                            Ensure(typeof(OrderedListState),thisNest,false,true);
                            if ((bool)Federation.Application["RemoveListItemWhitespace"] == false)
                            {
                                _output.WriteListItem(each);
                            }
                            else
                            {
                                _output.WriteListItem(each.Trim());
                            }
                            indiceCount[stateStack.Count-1] = indiceCount[stateStack.Count-1] + 1 ;
                        }
                        else if (each.StartsWith("#!"))
                        {
                            each = each.Substring(2);
                            if(CurrentState.GetType().ToString().Equals(typeof(UnorderedListState).ToString()) ||
                               CurrentState.GetType().ToString().Equals(typeof(OrderedListState).ToString()))
                                resetCount = false ;
                            else
                                resetCount = true ;
                            Ensure(typeof(OrderedListState),thisNest,resetCount,false);
                            if ((bool)Federation.Application["RemoveListItemWhitespace"] == false)
                            {
                                _output.WriteListItem(each);
                            }
                            else
                            {
                                _output.WriteListItem(each.Trim());
                            }
                            // Reset the list all levels
                            for(int i=0;i<35;i++)
                                indiceCount[i] = 1 ;
                            resetNextCount = true ;
                            Ensure(typeof(OrderedListState),0,false,false);
                        }
                        else if (each.StartsWith("#"))
                        {
                            each = each.Substring(1);
                            if(CurrentState.GetType().ToString().Equals(typeof(UnorderedListState).ToString()) ||
                               CurrentState.GetType().ToString().Equals(typeof(OrderedListState).ToString()))
                                resetCount = false ;
                            else
                                resetCount = true ;
                            if(resetNextCount)
                            {
                               resetCount = true ;
                               resetNextCount = false ;
                            }
                            Ensure(typeof(OrderedListState),thisNest,resetCount,false);
                            if ((bool)Federation.Application["RemoveListItemWhitespace"] == false)
                            {
                                _output.WriteListItem(each);
                            }
                            else
                            {
                                _output.WriteListItem(each.Trim());
                            }
                            indiceCount[stateStack.Count-1] = indiceCount[stateStack.Count-1] + 1 ;
                        }
                        else
                        {
                            // False alarm (just some tabs)
                            _output.Write(Regex.Replace(each, "\t", "        "));
                        }
                    }
                    else if (each.StartsWith("||") && each.EndsWith("||") && each.Length >= 4)
                    {
                        bool firstRow = !(CurrentState is TableState);
                        Ensure(typeof(TableState),0,false,false);
                        TableState ts = (TableState) CurrentState;

                        string endless = each.Substring(2, each.Length - 4);

                        // Write the row
                        bool firstCell = true;
                        foreach (string eachCell in Regex.Split(endless, @"\|\|"))
                        {
                            string cellContent = eachCell;
                            // Check the cell for formatting
                            TableCellInfo info = new TableCellInfo();
                            if (cellContent.StartsWith("{"))
                            {
                                int end = cellContent.IndexOf("}", 1);
                                if (end != -1)
                                {
                                    string fmt = cellContent.Substring(1, end - 1);
                                    cellContent = cellContent.Substring(end + 1);
                                    string result = info.Parse(fmt);
                                    if (result != null)
                                        cellContent = "(Error: " + result + ") " + cellContent;
                                }
                            }
                            if (firstCell)
                            {
                                if (firstRow)
                                {
                                    ts.HasBorder = info.HasBorder;
                                    Output.WriteOpenTable(info.TableAlignment, info.HasBorder, info.TableWidth);
                                }
                                _output.WriteOpenTableRow();
                            }
                            _output.WriteTableCell(ProcessLineElements(cellContent), info.IsHighlighted, info.CellAlignment, info.ColSpan, info.RowSpan, ts.HasBorder, info.AllowBreaks, info.CellWidth, info.BackgroundColor);
                            firstCell = false;
                        }
                        _output.WriteCloseTableRow();
                    }
                    else
                    {
                        Ensure(typeof(NeutralState),0,false,false);

                        // See if we've got a heading prefix
                        int heading = -1;
                        if (each.StartsWith("!!!!!!!"))
                            heading = 7;
                        else if (each.StartsWith("!!!!!!"))
                            heading = 6;
                        else if (each.StartsWith("!!!!!"))
                            heading = 5;
                        else if (each.StartsWith("!!!!"))
                            heading = 4;
                        else if (each.StartsWith("!!!"))
                            heading = 3;
                        else if (each.StartsWith("!!"))
                            heading = 2;
                        else if (each.StartsWith("!"))
                            heading = 1;

                        if (heading != -1)
                        {
                            _output.WriteHeading(each.Substring(heading), ProcessLineElements(each.Substring(heading)), _headingLevelBase + heading);
                        }
                        else
                        {
                            // If it's a single-line propertyName, wrap it visually
                            if (TopicParser.PropertyRegex.IsMatch(each))
                            {
                                Match m = TopicParser.PropertyRegex.Match(each);
                                string name = m.Groups["name"].Value;
                                string val = m.Groups["val"].Value;
                                string leader = m.Groups["leader"].Value;
                                bool isLeader = leader == ":";

                                // Write out an anchor tag.
                                if (isLeader)	// Only bother writing anchor and name for hidden page properties
                                {
                                    _output.WriteOpenAnchor(name);
                                    _output.WriteCloseAnchor();
                                }
                                else
                                {
                                    // Do the normal processing
                                    string linkedName = LinkWikiNames(name);

                                    val = val.Trim();
                                    val = ProcessLineElements(val);

                                    _output.WriteOpenProperty(linkedName);
                                    _output.WriteOpenAnchor(name);
                                    _output.Write(val);
                                    _output.WriteCloseAnchor();
                                    _output.WriteCloseProperty();
                                }
                            }
                            else if (true == each.StartsWith(BehaviorDelimiter))
                            {
                                // Don't wrap behaviors in <p> and </p>.
                                paraOpen = false;
                                each = ProcessLineElements(each);
                                _output.Write(each);
                            }
                            else
                            {
                                // As vanilla as can be -- just send it along
                                each = ProcessLineElements(each);
                                EnsureParaOpen();
                                _output.Write(each);
                            }
                        }
                    }
                }
                EnsureParaClose();
                if (false == currentMultilinePropertyIsHidden)
                {
                    _output.WriteEndLine();
                }
                _currentLineIndex++;
            }
            Ensure(typeof(NeutralState),0,false,false);            _output.End();

            CurrentState = null;	// Make sure to do this so the last state gets Exit()
        }
コード例 #26
0
 public static TopicNotFoundException ForTopic(TopicRevision topic)
 {
     TopicNotFoundException answer = new TopicNotFoundException("Topic not found: " + topic.ToString());
     answer.Topic = topic;
     return answer;
 }