Пример #1
0
		public DynamicTopic DynamicTopicFor(string topic)
		{
			if (_Topics == null)
				_Topics = new Hashtable();
			DynamicTopic answer = (DynamicTopic)(_Topics[topic]);
			if (answer != null)
				return answer;

			RelativeTopicName rel = new RelativeTopicName(topic);
			ArrayList alternatives = new ArrayList();
			if (rel.Namespace != null)	// if they left the namespace unspec'd
			{			
				alternatives.Add(new AbsoluteTopicName(topic));	
			}
			else
			{
				alternatives.Add(new AbsoluteTopicName(topic, Name));	// always try this one first
				alternatives.AddRange(rel.AllAbsoluteTopicNamesFor(CurrentFederation.ContentBaseForNamespace(Name)));
			}

			foreach (AbsoluteTopicName tn in alternatives)
			{
				ContentBase cb = CurrentFederation.ContentBaseForTopic(tn);
				if (!cb.TopicExists(tn))
					continue;
				answer = new DynamicTopic(CurrentFederation, tn);
				_Topics[topic] = answer;
				return answer;
			}
			return null;
		}
Пример #2
0
		/// <summary>
		/// Main formatting function.  The process of formatting the input to the output starts here.
		/// </summary>
		public void Format()
		{
			if (Federation.GetPerformanceCounter(Federation.PerformanceCounterNames.TopicFormat) != null)
				Federation.GetPerformanceCounter(Federation.PerformanceCounterNames.TopicFormat).Increment();


			CurrentState = new NeutralState(this);
			_CurrentLineIndex = 0;
			bool inMultilineProperty = false;
			bool currentMultilinePropertyIsHidden = false;
			string multiLinePropertyDelim = null;
			bool inPreBlock=false;
			bool inExtendedPreBlock = false;
			string preBlockKey=null;

			_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));
						inPreBlock = false;
						preBlockKey = null;
					}
					else
					{
						if (false == currentMultilinePropertyIsHidden)
						{
							each = each.Replace("\t", "		");
							if (inExtendedPreBlock)
							{
								each = ProcessLineElements(each);
							}
							_Output.Write(each);
							_Output.WriteEndLine();
						}
						_CurrentLineIndex++;
					}
					continue;
				}
				else if ( !inMultilineProperty && (each.StartsWith("{+") || each.StartsWith("{@")) )
				{
					Ensure(typeof(PreState));
					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 property.
				if (!inMultilineProperty && ContentBase.MultilinePropertyRegex.IsMatch(each))
				{
					// OK, here we go -- time to output the header
					Match m = ContentBase.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 = ContentBase.ClosingDelimiterForOpeningMultilinePropertyDelimiter(delim);
					currentMultilinePropertyIsHidden = leader == ":";
					if (currentMultilinePropertyIsHidden) // just write the anchor for hidden page properties
					{
						_Output.WriteOpenAnchor(name);
						_Output.WriteCloseAnchor();
						_Output.WriteLine("");
					}
					else
					{
						// 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 (ContentBase.IsBehaviorPropertyDelimiter(delim))
							_Output.Write(delim);
						_Output.Write(val);
					}
					inMultilineProperty = true;
					continue;
				}

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

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


				if (Formatter.StripExternalWikiDef(_ExternalWikiMap, each)) 
					continue;
        
				// empty line resets everything (except pre and multiline properties )
				if (each.Trim().Length == 0)
				{
					if (!(CurrentState is PreState) || (CurrentState is PreState && !IsNextLinePre()))
						Ensure(typeof(NeutralState));
					_Output.WriteEndLine();
				}
				else if ((each.StartsWith("----")) && (false == currentMultilinePropertyIsHidden))
				{
					Ensure(typeof(NeutralState));
					_Output.WriteRule();
				}
					// insert topic -- {{IncludeSomeTopic}} ?
				else if ((!each.StartsWith(" ") & Regex.IsMatch(each, @"^[\t]*\{\{" + wikiName + @"\}\}[\s]*$")) && 
					(false == currentMultilinePropertyIsHidden))
				{
					Regex nameGetter = new Regex("(?<topic>" + wikiName + ")");
					string name = nameGetter.Matches(each)[0].Groups["topic"].Value;
					RelativeTopicName topicName = new RelativeTopicName(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));
					AddCacheRule(ContentBase.CacheRuleForAllPossibleInstancesOfTopic(topicName));
					if (ContentBase.TopicExists(topicName)) 
					{
						if ((!IsBeyondSafeNestingDepth) && (false == currentMultilinePropertyIsHidden))
						{
							_Output.Write(IncludedTopic(topicName, _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));
					_Output.Write(Regex.Replace(each, "\t", "        "));
				}

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

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

					// See if this is a bullet line
					if (each.StartsWith("\t"))
					{
						each = ProcessLineElements(each);
						// Starts with a tab - might be a list (we'll see)
						// Count the tabs
						int 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
							Ensure(typeof(UnorderedListState));
							((UnorderedListState)(CurrentState)).SetNesting(thisNest);
							_Output.WriteListItem(each);
						}
						else if (each.StartsWith("1."))
						{
							each = each.Substring(2);
							Ensure(typeof(OrderedListState));
							((OrderedListState)(CurrentState)).SetNesting(thisNest);
							_Output.WriteListItem(each);
						}
						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));
						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));

						// 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(ProcessLineElements(each.Substring(heading)), _HeadingLevelBase + heading);
						}
						else
						{
							// If it's a single-line field, wrap it visually
							if (ContentBase.PropertyRegex.IsMatch(each))
							{
								Match m = ContentBase.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
							{
								// As vanilla as can be -- just send it along
								each = ProcessLineElements(each);
								EnsureParaOpen();
								_Output.Write(each);
							}
						}
					}
				}
				EnsureParaClose();
				if (false == currentMultilinePropertyIsHidden)
				{
					_Output.WriteEndLine();
				}
				_CurrentLineIndex++;
			}
    
			_Output.End();

			CurrentState = null;	// Make sure to do this so the last state gets Exit()
		}
Пример #3
0
		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();
				
				RelativeTopicName relName = new RelativeTopicName(TopicName.StripEscapes(each));

				// Ignore apparent links to non-existent namespaces.
				if ((null == relName.Namespace) || (null != TheFederation.ContentBaseForNamespace(relName.Namespace)))
				{
					// Build a list of all the possible absoluteNames for this topic
					ArrayList absoluteNames = new ArrayList();
					// Start with the singulars in the various reachable namespaces, then add the plurals
					absoluteNames.AddRange(ContentBase.AllAbsoluteTopicNamesThatExist(relName));
					AddCacheRule(ContentBase.CacheRuleForAllPossibleInstancesOfTopic(relName));
					foreach (TopicName alternate in relName.AlternateForms)
					{
						AddCacheRule(ContentBase.CacheRuleForAllPossibleInstancesOfTopic(alternate));
						absoluteNames.AddRange(ContentBase.AllAbsoluteTopicNamesThatExist(alternate));
					}
					
					// Now see if we got any hits or not
					string rep = beforeOrRelabel + "(" + RegexEscapeTopic(each) + ")" + afterWikiName;
					AbsoluteTopicName appearedAs = new AbsoluteTopicName(each);  // in case it was a plural form, be sure to show it as it appeared
					string displayname = TopicName.StripEscapes((ContentBase.DisplaySpacesInWikiLinks ? appearedAs.FormattedName : appearedAs.Name));
					if (relabel.Length > 0)
					{
						displayname = relabel;
					}

					if (absoluteNames.Count == 0)
					{
						if (!IsUnbracketedOneWordName(each))
						{
							// It doesn't exist, so give the option to create it
							AbsoluteTopicName abs = relName.AsAbsoluteTopicName(ContentBase.Namespace);
							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 (absoluteNames.Count == 1)
						{
							// The simple case is that there's only one link to point to, so we output just a normal link
							AbsoluteTopicName abs = (AbsoluteTopicName)absoluteNames[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>";
							}
							tipHTML += "<div class=\"TopicTipStats\">" + TheFederation.GetTopicModificationTime(abs).ToString() + " - " + TheFederation.GetTopicLastModifiedBy(abs) + "</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);
							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 (AbsoluteTopicName eachAbs in absoluteNames)
							{	
								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.Fullname + after);
				}
			}

			// Add on whatever's not yet been consumed
			answer.Append(str);
			return answer.ToString();
		}
Пример #4
0
		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/#property
				//		Case 3 - Inline the property value

				if (path == "" || path == "/")
				{
					// We've got only a topic
					RelativeTopicName topicName = new RelativeTopicName(authority);
					// See if we want the whole topic or just a property (via a fragment)
					if (fragment != "")
					{
						// Case 3 -- Ask for a property
						AbsoluteTopicName abs = null;
						bool ambig = false;
						AddCacheRule(ContentBase.CacheRuleForAllPossibleInstancesOfTopic(topicName));
						try
						{
							abs = ContentBase.UnambiguousTopicNameFor(topicName);
						}
						catch (TopicIsAmbiguousException)
						{
							ambig = true;
						}
						string replacement;
						if (abs != null)
						{
							// Got a unique URI it!
							replacement = TheFederation.GetTopicProperty(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
					AbsoluteTopicName abs = null;
					RelativeTopicName topicName = new RelativeTopicName(authority);
					bool ambig = false;
					AddCacheRule(ContentBase.CacheRuleForAllPossibleInstancesOfTopic(topicName));
					try
					{
						abs = ContentBase.UnambiguousTopicNameFor(topicName);
					}
					catch (TopicIsAmbiguousException)
					{
						ambig = true;
					}
					string replacement;
					if (abs != null)
					{
						// Got a unique URI it!
						string uriForLibrary = TheFederation.GetTopicProperty(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;
		}
Пример #5
0
    /// <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(AbsoluteTopicName name, Border border, CompositeCacheRule rule)
    {
      ArrayList answer = new ArrayList();
      ContentBase cb;
      string bordersTopicsProperty = "Borders";

      ArrayList borderTopics = new ArrayList();   
    
   
      // Start with whatever the namespace defines
      if (Borders != null)
      {
        foreach (string at in ParseListPropertyValue(Borders))
        {
          AbsoluteTopicName abs = new AbsoluteTopicName(at);
          cb = ContentBaseForTopic(abs);
          if (abs == null || cb == 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
      cb = ContentBaseForTopic(name);
      if (cb != null)
      {
        borderTopics.AddRange(GetTopicListPropertyValue(cb.DefinitionTopicName, bordersTopicsProperty));
        rule.Add(cb.CacheRuleForAllPossibleInstancesOfTopic(cb.DefinitionTopicName));
      }

      // 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 (cb == null || cb.DefinitionTopicName.ToString() !=  name.ToString())
      {
        borderTopics.AddRange(GetTopicListPropertyValue(name, bordersTopicsProperty));
      }


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

      return answer;
    }
Пример #6
0
		protected void DoHead()
		{


			AbsoluteTopicName topic = GetTopicName();	 
			LinkMaker lm = TheLinkMaker;

			// Consider establishing a redirect if there's a redirect to a topic or an URL
			string redir = TheFederation.GetTopicProperty(GetTopicName(), "Redirect");
			if (redir != "")
			{
				UriBuilder URI = null;
				if (IsAbsoluteURL(redir)) 
				{
					URI = new UriBuilder(redir);
				}
				else
				{
					// Must be a topic name
					string trimmed = redir.Trim();
					RelativeTopicName rel = new RelativeTopicName(trimmed);
					IList all = TheFederation.ContentBaseForTopic(GetTopicName()).AllAbsoluteTopicNamesThatExist(rel);

					if (all.Count == 1) 
					{
						URI = new UriBuilder(lm.LinkToTopic((TopicName)(all[0]), false, Request.QueryString));
					}
					else
					{
						if (all.Count == 0)
							Response.Write("<!-- Redirect topic does not exist -->\n");
						else
							Response.Write("<!-- Redirect topic is ambiguous -->\n");
					}
				}
				if (URI != null)
				{
					if (Request.QueryString["DelayRedirect"] == "1")
						Response.Write(@"<meta http-equiv='refresh' content='10;URL=" + URI + "'>\n");
					else
					{
						Response.Redirect(URI.Uri.ToString());
						return;
					}
				}
			}

			string keywords = TheFederation.GetTopicProperty(GetTopicName(), "Keywords");
			if (keywords != "")
				Response.Write("<META name=\"keywords\" content=\"" + keywords + "\">\n");
			string description = TheFederation.GetTopicProperty(GetTopicName(), "Summary");
			if (description != "")
				Response.Write("<META name=\"description\" content=\"" + description + "\">\n");
			Response.Write("<META name=\"author\" content=\"" + TheFederation.GetTopicLastModifiedBy(GetTopicName()) + "\">\n");

			if (GetTopicName().Version != null)
			{
				// Don't index the versions
				Response.Write("<meta name=\"Robots\" content=\"NOINDEX, NOFOLLOW\">");
			}
        
			urlForDiffs = lm.LinkToTopic(topic, true);
			urlForNoDiffs = lm.LinkToTopic(topic, false);
		}
Пример #7
0
		string TopicLink(string top, bool showDiffs, NameValueCollection extraQueryParms)
		{
			StringBuilder builder = new StringBuilder();
			RelativeTopicName topic = new RelativeTopicName(top);
			builder.Append(SiteURL());
			builder.Append("default.aspx/");
			if (topic.Namespace != null && topic.Namespace != "")
				builder.Append(HttpUtility.UrlEncode(topic.Namespace) + "/");
			builder.Append(topic.Name);
			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();
		}
Пример #8
0
		/// <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>
		public  bool RenameTopicReferences(LocalTopicName topicToLookIn, AbsoluteTopicName oldName, AbsoluteTopicName newName, FederationUpdateGenerator gen)
		{
			string current = Read(topicToLookIn);
			MatchCollection wikiNames = Formatter.extractWikiNames.Matches(current);
			ArrayList processed = new ArrayList();
			bool any = false;
			foreach (Match m in wikiNames)
			{
				string each = m.Groups["topic"].ToString();
				if (processed.Contains(each))
				{
					continue;   // skip dup	
				}
				processed.Add(each);
			
				RelativeTopicName relName = new RelativeTopicName(TopicName.StripEscapes(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.Name == oldName.Name) && (relName.Namespace == null || relName.Namespace ==  oldName.Namespace);
				if (!hit)
					continue;

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

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

			return any;
		}
Пример #9
0
		/// <summary>
		/// Answer a hash: keys are topic; values are an array of topic names for referenced topics (in this content base)
		/// </summary>
		/// <param name="filterToTopic">Specific topic for which reference information is desired (null gets info for all topics)</param>
		/// <param name="existingOnly">Specific whether to only return the referenced topics that actually exist</param>
		/// <returns></returns>
		public Hashtable AllReferencesByTopic(AbsoluteTopicName filterToTopic, bool existingOnly)
		{
			Hashtable relativesToRefs = new Hashtable();
			Hashtable answer = new Hashtable();
			IEnumerable topicList;

			if (filterToTopic == null)
				topicList = AllTopics(false);
			else 
			{
				ArrayList list = new ArrayList();
				list.Add(filterToTopic);
				topicList = list;
			}

			foreach (AbsoluteTopicName topic in topicList)
			{
				string current = Federation.Read(topic);
				MatchCollection wikiNames = Formatter.extractWikiNames.Matches(current);
				ArrayList processed = new ArrayList();
				ArrayList allReferencedTopicsFromTopic = new ArrayList();
				foreach (Match m in wikiNames)
				{
					string each = m.Groups["topic"].ToString();
					if (processed.Contains(each))
					{
						continue;   // skip dup	
					}
					processed.Add(each);
				
					RelativeTopicName relName = new RelativeTopicName(TopicName.StripEscapes(each));
					
					// Now either calculate the full list of referenced names and cache it or get it from the cache
					ArrayList absoluteNames = (ArrayList)(relativesToRefs[relName]);
					if (absoluteNames == null)
					{
						absoluteNames = new ArrayList();
						relativesToRefs[relName] = absoluteNames;
						// Start with the singulars in the various reachable namespaces, then add the plurals
						if (existingOnly)
						{
							absoluteNames.AddRange(AllAbsoluteTopicNamesThatExist(relName));
							foreach (TopicName alternate in relName.AlternateForms)
								absoluteNames.AddRange(AllAbsoluteTopicNamesThatExist(alternate));
						}
						else
						{
							absoluteNames.AddRange(relName.AllAbsoluteTopicNamesFor(this));
							foreach (TopicName alternate in relName.AlternateForms)
								absoluteNames.AddRange(alternate.AllAbsoluteTopicNamesFor(this));
						}
					}
					allReferencedTopicsFromTopic.AddRange(absoluteNames);
				}
				answer[topic] = allReferencedTopicsFromTopic;
			}
			return answer;
		}
Пример #10
0
		public string Property(ExecutionContext ctx, string topic, string property)
		{
			AbsoluteTopicName abs = null;
			bool ambig = false;
			string answer = null;
			try
			{
				ContentBase cb = ctx.CurrentContentBase;
				if (cb == null)
					cb = ctx.CurrentFederation.DefaultContentBase;
				RelativeTopicName rel = new RelativeTopicName(topic);
				ctx.AddCacheRule(cb.CacheRuleForAllPossibleInstancesOfTopic(rel));
				abs = cb.UnambiguousTopicNameFor(rel);
			}
			catch (TopicIsAmbiguousException)
			{
				ambig = true;
			}
			if (abs != null)
			{
				// Got a unique one!
				answer = ctx.CurrentFederation.GetTopicProperty(abs, property);
			}
			else
			{
				if (ambig)
					throw new ArgumentException("Ambiguous topic name: " + topic);
				else
					throw new ArgumentException("Unknown topic name: " + topic);
			}
			return answer;
		}
Пример #11
0
		public IEnumerable GetAllNewsletterNames(string namespaceFilter)
		{
			ArrayList answer = new ArrayList();
			foreach (ContentBase cb in TheFederation.ContentBases)
			{
				if (namespaceFilter != null && cb.Namespace != namespaceFilter)
					continue;
				foreach (string s in TheFederation.GetTopicListPropertyValue(cb.TopicNameFor("WikiNewsletterIndex"), "Newsletters"))
				{
					RelativeTopicName rel = new RelativeTopicName(s);
					answer.AddRange(cb.AllAbsoluteTopicNamesThatExist(rel));
				}
			}
			return answer;
		}
Пример #12
0
    // Updated 2004-01-29 by CraigAndera
    public IEnumerable AllTopicsForNewsletter(AbsoluteTopicName newsletter)
    {
      // HybridDictionary switches between using a ListDictionary and a Hashtable 
      // depending on the size of the collection - should be a good choice since we don't
      // know how big the collection of topic names will be 
      HybridDictionary answer = new HybridDictionary(); 

      ContentBase cb = ContentBaseForNewsletter(newsletter);

      foreach (string s in TheFederation.GetTopicListPropertyValue(newsletter, "Topics"))
      {
        // If the wildcard appears, ignore all the other topics listed - include every topic
        if (s == "*")
        {
          answer.Clear(); 
          foreach (AbsoluteTopicName atn in cb.AllTopics(false))
          {
            answer.Add(atn.Fullname, atn); 
          }
          // No need to continue iterating after we find the wildcard 
          break; 
        }
        else
        {
          RelativeTopicName rel = new RelativeTopicName(s);
          foreach (AbsoluteTopicName atn in cb.AllAbsoluteTopicNamesThatExist(rel))
          {
            answer.Add(atn.Fullname, atn); 
          }
        }
      }

      // Now we need to remove any topics that appear in the Exclude field
      foreach (string s in TheFederation.GetTopicListPropertyValue(newsletter, "Exclude"))
      {
        RelativeTopicName rel = new RelativeTopicName(s);
        foreach (AbsoluteTopicName atn in cb.AllAbsoluteTopicNamesThatExist(rel))
        {
          answer.Remove(atn.Fullname); 
        }
      }

      // Do the same for "Excludes", since it's hard to remember which one to use
      foreach (string s in TheFederation.GetTopicListPropertyValue(newsletter, "Excludes"))
      {
        RelativeTopicName rel = new RelativeTopicName(s);
        foreach (AbsoluteTopicName atn in cb.AllAbsoluteTopicNamesThatExist(rel))
        {
          answer.Remove(atn.Fullname); 
        }
      }

      return answer.Values;
    }