public DynamicTopic DynamicTopicFor(string topic) { if (_topics == null) { _topics = new Hashtable(); } DynamicTopic answer = (DynamicTopic)(_topics[topic]); if (answer != null) { return answer; } TopicName topicName = new TopicName(topic); QualifiedTopicNameCollection alternatives = new QualifiedTopicNameCollection(); if (topicName.IsQualified) { alternatives.Add(new QualifiedTopicName(topicName.LocalName, topicName.Namespace)); } else { alternatives.Add(new QualifiedTopicName(topicName.LocalName, Namespace)); NamespaceManager manager = CurrentFederation.NamespaceManagerForNamespace(Namespace); alternatives.AddRange(manager.AllPossibleQualifiedTopicNames(new UnqualifiedTopicName(topicName.LocalName))); } foreach (QualifiedTopicName tn in alternatives) { NamespaceManager namespaceManager = CurrentFederation.NamespaceManagerForTopic(tn); if (!namespaceManager.TopicExists(tn.LocalName, ImportPolicy.DoNotIncludeImports)) { continue; } answer = new DynamicTopic(CurrentFederation, new QualifiedTopicRevision(tn)); _topics[topic] = answer; return answer; } return null; }
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(); }
/// <summary> /// Returns a list of all topics in the namespace, sorted using the specified comparison. /// </summary> /// <param name="importPolicy">Indicates whether topics in imported namespaces /// should be included in the details.</param> /// <param name="sortCriterion">A <see cref="Comparision>QualifiedTopicName<"/> to use to /// sort the output, or null not to sort.</param> /// <returns>A (potentially sorted) list of <see cref="QualifiedTopicName"/> objects.</returns> /// <remarks>Order is not guaranteed in the absence of a sortCriteria.</remarks> public QualifiedTopicNameCollection AllTopics(ImportPolicy importPolicy, Comparison<QualifiedTopicName> sortCriterion) { QualifiedTopicNameCollection answer = new QualifiedTopicNameCollection(); QualifiedTopicNameCollection unsortedTopics = ContentProviderChain.AllTopics(); answer.AddRange(unsortedTopics); if (importPolicy == ImportPolicy.IncludeImports) { foreach (NamespaceManager namespaceManager in ImportedNamespaceManagers) { answer.AddRange(namespaceManager.AllTopics(ImportPolicy.DoNotIncludeImports)); } } if (sortCriterion != null) { answer.Sort(sortCriterion); } return answer; }