public string LinkToTopic(TopicRevision topic, bool showDiffs, NameValueCollection extraQueryParms) { return TopicLink(topic.DottedNameWithVersion, showDiffs, extraQueryParms); }
public static DuplicateTopicException ForTopic(TopicRevision tn) { DuplicateTopicException answer = new DuplicateTopicException("Duplicate topic: " + tn.ToString()); answer.Topic = tn; return answer; }
public string LinkToTopic(TopicRevision topic, bool showDiffs) { return TopicLink(topic.DottedNameWithVersion, showDiffs, null); }
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(); }
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; }
public string LinkToLogoff(TopicRevision topic) { return LinkToLogoff(topic); }
public string LinkToRestore(TopicRevision topic) { return RestoreLink(topic.DottedNameWithVersion); }
/// <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>
public NamespaceManager NamespaceManagerForTopic(TopicRevision topic, string nsRelativeTo) { if (topic.IsQualified) { return NamespaceManagerForNamespace(topic.Namespace); } return NamespaceManagerForNamespace(nsRelativeTo); }
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; }
/// <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); } }
internal static FlexWikiException VersionDoesNotExist(TopicRevision revision) { return VersionDoesNotExist(revision.Name, revision.Version); }
public bool TopicIsReadOnly(TopicRevision topic) { if (topic.IsQualified) { return Federation.TopicIsReadOnly(new QualifiedTopicRevision(topic.LocalName, topic.Namespace)); } else { return TopicIsReadOnly(topic.LocalName); } }
private static string MakeTopicFilename(TopicRevision topic) { if (topic.Version == null) { return topic.LocalName + ".wiki"; } else { return topic.LocalName + "(" + topic.Version + ").awiki"; } }
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(); }
/// <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]); }
public string LinkToLogin(TopicRevision topic) { return LinkToLogin(topic.DottedNameWithVersion); }
/// <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; }
public string LinkToPrintView(TopicRevision topic) { return PrintLink(topic.DottedNameWithVersion); }
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"; }
public static TopicIsAmbiguousException ForTopic(TopicRevision topic) { TopicIsAmbiguousException answer = new TopicIsAmbiguousException("Topic is ambiguous: " + topic.ToString()); answer.Topic = topic; return answer; }
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; }
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(); }
public string LinkToTopic(TopicRevision topic) { return LinkToTopic(topic, false); }
/// <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() }
public static TopicNotFoundException ForTopic(TopicRevision topic) { TopicNotFoundException answer = new TopicNotFoundException("Topic not found: " + topic.ToString()); answer.Topic = topic; return answer; }