//this is the main body where the real parsing work is done < 30 lines of code public WomDocument ProcessText(string wikiInput, QualifiedTopicRevision topic, NamespaceManager mgr, bool fragment, int size) { //_stopwatch = Stopwatch.StartNew(); ParserContext savedcontext; bool redo = false; wikiInput = wikiInput.Replace("\r\n\r\n", "\r\n"); if (!fragment) { wikiInput = "\r\n" + wikiInput; } else { while (wikiInput.EndsWith("\r\n")) { wikiInput = wikiInput.Remove(wikiInput.LastIndexOf("\r\n")); } } _womDocument = new WomDocument(null); _womDocument.Fed = _fed; _womDocument.Mgr = mgr; _womDocument.FragmentOnly = fragment; _womDocument.Begin(); int chunk = _chunk; //set the initial chunk size (for cache use) if (size > 0) { chunk = size; } chunkcnt = 1; while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } if (!String.IsNullOrEmpty(wikiInput)) { StringBuilder source = new StringBuilder(); StringBuilder temp = new StringBuilder(); source.AppendLine(externalWikiRef.Replace(wikiInput, new MatchEvaluator(externalWikiRefMatch))); temp.Append(multilinePre.Replace(source.ToString(), new MatchEvaluator(multilinePreMatch))); source = temp; string savedtemp = temp.ToString(); MatchCollection matches; while (source.Length > 0) { string womElement = _context.WomElement; //optimize here by passing in less than the full string when source is very long //this gives a 5 times performance improvement int matchcnt = 0; if (source.Length > chunk * chunkcnt) { matches = _context.RegExp.Matches(source.ToString(0, chunk * chunkcnt)); matchcnt = matches.Count; } else { matches = _context.RegExp.Matches(source.ToString()); matchcnt = matches.Count; } if (matchcnt > 0) { if (matches[0].Index > 0) { _womDocument.SimpleAdd(source.ToString(0, matches[0].Index), womElement, "", _context.RuleList[0]); } int x = 1; if (_context.RegExpStr.StartsWith("(?:") && !matches[0].Value.StartsWith("%")) { x = 0; } int cnt = matches[0].Groups.Count; for (int i = x; i < cnt; i++) { if (matches[0].Groups[i].Success) { if (womElement != "WikiText") { //we are in a child rule set with an end condition //whereas WikiText ends by running out of source or matches if (i == 1) { i = 0; } } if (_womDocument.InTable && _womDocument.InItem && matches[0].Value.StartsWith("%")) { i++; //add one to the index here as we are in womText rules twice for this condition } ParserRule rule = _context.RuleList[i]; savedcontext = _context; string addElement; if (!String.IsNullOrEmpty(rule.WomElement)) { addElement = rule.WomElement; } else { addElement = womElement; } _womDocument.SimpleAdd(matches[0].Value, addElement, rule.Jump, rule); if (_womDocument.ParsedDocument.Contains("<<")) //an error occurred { chunkcnt++; //increase the chunk size and redo redo = true; } else { if (addElement != "WikiStylingEnd") { _context = rule.Context; } //still in a line - only pop one context item else if (matches[0].Value == "%%" || matches[0].Value == "%" || matches[0].Value.Contains("{||")) { _context = _context.ParentRule.ParentContext; } else //done with that line - pop all context back to start { while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } } } break; } } if (!redo) //an error occurred { bool modifyRemove = false; if (womElement == "womListText" && matches[0].Value.Contains("{||")) //need to leave this bit in source { modifyRemove = true; } else if (womElement == "womWikiStyledText" && matches[0].Value == "%") { modifyRemove = true; } if (modifyRemove) { source.Remove(0, matches[0].Index); } else { source.Remove(0, matches[0].Index + matches[0].Length); } } else { //reset and start over with larger chunk source = new StringBuilder(); source.Append(savedtemp); _womDocument = new WomDocument(null); _womDocument.Fed = _fed; _womDocument.Mgr = mgr; _womDocument.FragmentOnly = fragment; _womDocument.Begin(); redo = false; while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } } } else { if (source.Length > chunk * chunkcnt) //no match in that chunk, increase size and retry { source = new StringBuilder(); source.Append(savedtemp); _womDocument = new WomDocument(null); _womDocument.Fed = _fed; _womDocument.Mgr = mgr; _womDocument.FragmentOnly = fragment; _womDocument.Begin(); chunkcnt++; while (_context.ParentRule != null) { if (_context.ParentRule.ParentContext != null) { _context = _context.ParentRule.ParentContext; } } } else { _womDocument.SimpleAdd(source.ToString(), womElement, "", _context.RuleList[0]); source.Length = 0; } } } source = null; temp = null; } _womDocument.End(); if (((bool)_fed.Application["DisableWikiEmoticons"] == false)) //&& (_mgr.DisableNamespaceEmoticons == false)) { MatchCollection emoticonMatches = findEmoticon.Matches(_womDocument.ParsedDocument); if (emoticonMatches.Count > 0) { _womDocument.ConvertEmoticons(emoticonMatches); } } //_stopwatch.Stop(); if (chunkcnt > 1) { mgr.SetProcessTextSize(topic.AsUnqualifiedTopicRevision(), chunk * chunkcnt); } return _womDocument; }
private string wikiBehaviorMatch(Match match) { string replacement = match.ToString(); string linestart = match.Groups["LineStart"].Value; string lineend = match.Groups["LineEnd"].Value; string expr = match.Groups["Behavior"].Value; match = null; bool doBehavior = false; if (insideTable.IsMatch(linestart)) { doBehavior = true; } else if (!preBehavior.IsMatch(linestart)) { doBehavior = true; } if (doBehavior) { TopicContext tc = new TopicContext(_fed, _mgr, new TopicVersionInfo(_fed, _behaviorTopic)); BehaviorInterpreter interpreter = new BehaviorInterpreter(_behaviorTopic == null ? "" : _behaviorTopic.DottedName, expr, _fed, _fed.WikiTalkVersion, this); if (!interpreter.Parse()) { //parse failed replacement = ErrorMessage(null, interpreter.ErrorString); } else { //parse succeeded if (!interpreter.EvaluateToPresentation(tc, _mgr.ExternalReferences)) { //eval failed replacement = ErrorMessage(null, interpreter.ErrorString); _processBehaviorToText = false; } else { //eval succeeded WikiOutput nOut = new WomDocument(null); interpreter.Value.OutputTo(nOut); replacement = nOut.ToString(); } } if (replacement.Contains("<script")) { replacement = Regex.Replace(replacement, @"<script(.*?)>", @"<script$1>", RegexOptions.Singleline); replacement = Regex.Replace(replacement, @"</script>", @"</script>"); } replacement = Regex.Replace(replacement, @"^\|\|", "||}", RegexOptions.Multiline); replacement = Regex.Replace(replacement, @" \|\|$| \|\|\r\n| \{\|\|\r\n|\|\|\r\n", " {||\r\n", RegexOptions.Multiline); replacement = Regex.Replace(replacement, @"(?<!\{|"""")\|\|(?!\}|"""")", @" {||}"); if (_processBehaviorToText) { replacement = replacement.Replace(" ", "\t"); replacement = escAmpersand.Replace(replacement, "&"); //full escape causes some pages to fail replacement = ProcessText(replacement, _behaviorTopic, _mgr, true, 350).ParsedDocument; } } replacement = linestart + replacement + lineend; return replacement; }
//this is where fragments are prepped for parsing public WomDocument FormatTextFragment(string wikiInput, QualifiedTopicRevision topic, NamespaceManager mgr, bool fragment, int sizeIn) { WomDocument xmldoc = new WomDocument(null); string wikitext = ""; _mgr = mgr; _topic = topic; WomDocument.ResetTableOfContents(); WomDocument.anchors = new string[25]; _processBehaviorToText = true; _behaviorTopic = topic; wikitext = escape(wikiInput); int size = 0; bool done = false; while (!done) { try { string tempsize = _mgr.GetTopicProperty(topic.AsUnqualifiedTopicRevision(), "_ProcessTextSize").LastValue; Int32.TryParse(tempsize, out size); if (size == 0) { size = sizeIn; } xmldoc = ProcessText(wikitext, topic, _mgr, fragment, size); //string womdoc = xmldoc.ParsedDocument; //string firstPass = findWikiBehavior.Replace(womdoc, new MatchEvaluator(wikiBehaviorMatch)); //xmldoc.ParsedDocument = findWikiBehavior.Replace(firstPass, new MatchEvaluator(wikiBehaviorMatch)); while (findWikiBehavior.IsMatch(xmldoc.ParsedDocument)) { xmldoc.ParsedDocument = findWikiBehavior.Replace(xmldoc.ParsedDocument, new MatchEvaluator(wikiBehaviorMatch)); } _behaviorTopic = null; if (findIncludedTopic.IsMatch(xmldoc.ParsedDocument)) { string included = xmldoc.ParsedDocument; included = findIncludedTopic.Replace(included, new MatchEvaluator(wikiIncludedTopic)); xmldoc.ParsedDocument = included; } done = true; //interpreted = xmldoc.ParsedDocument; //xmldoc = null; } catch (XmlException ex) { _mgr.SetProcessTextSize(topic.AsUnqualifiedTopicRevision(), size * (chunkcnt + 1)); string error = "<Error>" + ex.ToString() + "</Error>"; xmldoc.ParsedDocument = error; } } return xmldoc; }
public string FormattedTopic(QualifiedTopicRevision topic, OutputFormat fmt) { //initial version does not handle diffs string wikitext = ""; string interpreted = ""; _mgr = _fed.NamespaceManagerForNamespace(topic.Namespace); _topic = topic; WomDocument.ResetTableOfContents(); WomDocument.anchors = new string[25]; _processBehaviorToText = true; _behaviorTopic = topic; //Normally get data from the cache, but when debugging Womdocument need to avoid using cached data string wom = _mgr.GetTopicProperty(topic.AsUnqualifiedTopicRevision(), "_Wom").LastValue; //string wom = ""; if (!String.IsNullOrEmpty(wom)) { WomDocument xmldoc = new WomDocument(null); wom = findWikiBehavior.Replace(wom, new MatchEvaluator(wikiBehaviorMatch)); xmldoc.ParsedDocument = findWikiBehavior.Replace(wom, new MatchEvaluator(wikiBehaviorMatch)); if (findIncludedTopic.IsMatch(xmldoc.ParsedDocument)) { string included = xmldoc.ParsedDocument; included = findIncludedTopic.Replace(included, new MatchEvaluator(wikiIncludedTopic)); xmldoc.ParsedDocument = included; } interpreted = xmldoc.ParsedDocument; xmldoc = null; } else { using (TextReader sr = _mgr.TextReaderForTopic(topic.AsUnqualifiedTopicRevision())) { wikitext = sr.ReadToEnd() + "\r\n"; } wikitext = escape(wikitext); int size = 0; while (String.IsNullOrEmpty(interpreted)) { try { string tempsize = _mgr.GetTopicProperty(topic.AsUnqualifiedTopicRevision(), "_ProcessTextSize").LastValue; Int32.TryParse(tempsize, out size); if (size == 0) { size = _chunk; } WomDocument xmldoc = ProcessText(wikitext, topic, _mgr, false, size); //string womdoc = xmldoc.ParsedDocument; _mgr.SetWomCache(topic.AsUnqualifiedTopicRevision(), xmldoc.ParsedDocument); //string firstPass = findWikiBehavior.Replace(womdoc, new MatchEvaluator(wikiBehaviorMatch)); //xmldoc.ParsedDocument = findWikiBehavior.Replace(firstPass, new MatchEvaluator(wikiBehaviorMatch)); while (findWikiBehavior.IsMatch(xmldoc.ParsedDocument)) { xmldoc.ParsedDocument = findWikiBehavior.Replace(xmldoc.ParsedDocument, new MatchEvaluator(wikiBehaviorMatch)); } _behaviorTopic = null; if (findIncludedTopic.IsMatch(xmldoc.ParsedDocument)) { string included = xmldoc.ParsedDocument; included = findIncludedTopic.Replace(included, new MatchEvaluator(wikiIncludedTopic)); xmldoc.ParsedDocument = included; } interpreted = xmldoc.ParsedDocument; xmldoc = null; } catch (XmlException ex) { _mgr.SetProcessTextSize(topic.AsUnqualifiedTopicRevision(), size * (chunkcnt + 1)); string error = ex.ToString(); } } } _processBehaviorToText = false; return interpreted; }
public string FormattedTopic(QualifiedTopicRevision topic, OutputFormat fmt, QualifiedTopicRevision diff) { string wikitext = ""; //OutputFormat is not really used at this point but is retained as it would be the selector for the xslt file to be used if (diff == null) { WomDocument topicDoc = new WomDocument(null); topicDoc.ParsedDocument = FormattedTopic(topic, fmt); wikitext = WikiToPresentation(topicDoc.XmlDoc); } else { ArrayList styledLines = new ArrayList(); IList leftLines; IList rightLines; string leftString = FormattedTopic(topic, fmt); string rightString = FormattedTopic(diff, fmt); leftLines = leftString.Replace("\r", "").Split('\n'); rightLines = rightString.Replace("\r", "").Split('\n'); IEnumerable diffs = Diff.Compare(leftLines, rightLines); WomDocument diffDoc = new WomDocument(null); foreach (LineData ld in diffs) { LineStyle style = LineStyle.Unchanged; switch (ld.Type) { case LineType.Common: style = LineStyle.Unchanged; break; case LineType.LeftOnly: style = LineStyle.Add; break; case LineType.RightOnly: style = LineStyle.Delete; break; } if (ld.Text != "</WomDocument>") { diffDoc.AddDiff(ld.Text + "\r\n", style); } } diffDoc.AddDiff("</WomDocument>", LineStyle.Unchanged); wikitext = WikiToPresentation(diffDoc.XmlDoc); //Format(topic, styledLines, output, relativeToBase, linker, relativeToBase.ExternalReferences, 0); } return wikitext; }
public string ErrorMessage(string title, string body) { // We can't use the fancy ErrorString method -- it didn't exist in v0 WikiOutput nOut = new WomDocument(null); nOut.WriteErrorMessage(title, body); return nOut.ToString(); }
public void BuildFeed() { QualifiedTopicRevision topic = GetTopicVersionKey(); NamespaceManager storeManager = Federation.NamespaceManagerForTopic(topic); LinkMaker lm = TheLinkMaker; ArrayList entryList = new ArrayList(); StringBuilder feed = new StringBuilder(); StringBuilder errFeed = new StringBuilder(); StringBuilder errEntry = new StringBuilder(); bool feedInit = false; bool feedError = false; bool entryError = false; string author = ""; string feedTitle = ""; string feedUUID = ""; string feedLogo = ""; string feedIcon= ""; string blogCategory =""; feed.AppendLine(@"<?xml version=""1.0"" encoding=""utf-8""?>"); feed.AppendLine(@"<!DOCTYPE message ["); feed.AppendLine("<!ENTITY nbsp \" \"> ]>"); feed.AppendLine(@"<feed xmlns=""http://www.w3.org/2005/Atom"">"); errFeed.AppendLine(@"<pre id=""Error"" class=""Error"" style=""background: #F00;"">"); errFeed.AppendLine("The Feed errors described below need to be corrected"); if (storeManager.GetTopicInfo(topic.LocalName).HasProperty("Title")) { feedTitle = storeManager.GetTopicProperty(topic.LocalName, "Title").LastValue; } else { feedError = true; } if (storeManager.GetTopicInfo(topic.LocalName).HasProperty("Creator")) { author = storeManager.GetTopicProperty(topic.LocalName, "Creator").LastValue; } string feedLink = BaseUrl + lm.LinkToTopic(topic); if (storeManager.GetTopicInfo(topic.LocalName).HasProperty("FeedUUID")) { feedUUID = storeManager.GetTopicProperty(topic.LocalName, "FeedUUID").LastValue; } else { feedError = true; } if (storeManager.GetTopicInfo(topic.LocalName).HasProperty("FeedLogo")) { feedLogo = storeManager.GetTopicProperty(topic.LocalName, "FeedLogo").LastValue; } if (storeManager.GetTopicInfo(topic.LocalName).HasProperty("FeedIcon")) { feedIcon = storeManager.GetTopicProperty(topic.LocalName, "FeedIcon").LastValue; } if (storeManager.GetTopicInfo(topic.LocalName).HasProperty("BlogCategory")) { blogCategory = storeManager.GetTopicProperty(topic.LocalName, "BlogCategory").LastValue; } if (storeManager.GetTopicInfo(topic.LocalName).HasProperty("BlogTopics")) { entryList = storeManager.GetTopicInfo(topic.LocalName).GetListProperty("BlogTopics"); } ParserEngine _parser = new ParserEngine(storeManager.Federation); errEntry.AppendLine(@"<pre id=""Error"" class=""Error"" style=""background: #F00;"">"); errEntry.AppendLine("The Entry errors described below need to be corrected"); if (entryList.Count > 0) { foreach (string entryTopicName in entryList) { string entryTitle = ""; string entryAuthor = ""; string entryLink = ""; string entryUUID = ""; string entryContent = ""; System.DateTime lastModified = new DateTime(); QualifiedTopicRevision entryTopicRev = new QualifiedTopicRevision(entryTopicName, storeManager.Namespace); TopicVersionInfo topicVerInfo = new TopicVersionInfo(storeManager.Federation, entryTopicRev); if (topicVerInfo.Exists) { if (storeManager.GetTopicInfo(entryTopicName).HasProperty("Creator")) { entryAuthor = storeManager.GetTopicProperty(entryTopicName, "Creator").LastValue; if (String.IsNullOrEmpty(author)) { author = entryAuthor; } } else { if (!String.IsNullOrEmpty(author)) { entryAuthor = author; } else { feedError = true; errFeed.AppendLine(" Error: The feed does not have a property named 'Creator' or the property does not contain a value."); author = "Author Unspecified"; entryAuthor = author; } } if (storeManager.GetTopicInfo(entryTopicName).HasProperty("Title")) { entryTitle = storeManager.GetTopicProperty(entryTopicName, "Title").LastValue; } else { entryTitle = storeManager.GetTopicInfo(entryTopicName).ExposedFormattedName; } lastModified = storeManager.GetTopicLastModificationTime(entryTopicName).ToUniversalTime(); if (!feedInit) { if (feedError) { feedError = true; if (entryList.Count == 0) { errFeed.AppendLine("Error: Feed does not have a property 'BlogTopics' or that property value is empty"); } if (!String.IsNullOrEmpty(feedTitle)) { feed.AppendFormat(@"<title>{0}</title>", feedTitle); } else { feed.AppendLine("<title>Feed title Unspecified</title>"); errFeed.AppendLine("Error: Feed does not have a property 'Title' or value is empty."); } feed.AppendLine(@"<author>"); feed.AppendFormat(@"<name>{0}</name>", author); feed.AppendLine(@"</author>"); if (!String.IsNullOrEmpty(feedUUID)) { feed.AppendFormat(@"<id>urn:uuid:{0}</id>", feedUUID); } else { feed.AppendFormat(@"<id>urn:uuid:{0}</id>", System.Guid.NewGuid().ToString()); errFeed.AppendLine("Error: Feed does not have a property 'FeedUUID' or value is empty. A temporary value has been assigned"); } feed.AppendFormat(@"<updated>{0:s}Z</updated>", lastModified); if (!String.IsNullOrEmpty(feedLogo)) { feed.AppendFormat(@"<logo>{0}</logo>", feedLogo); } if (!String.IsNullOrEmpty(feedIcon)) { feed.AppendFormat(@"<icon>{0}</icon>", feedIcon); } if (!String.IsNullOrEmpty(blogCategory)) { feed.AppendFormat(@"<category term=""{0}"" />", blogCategory); } errFeed.AppendLine("</pre>"); } else { feed.AppendFormat(@"<title>{0}</title>", feedTitle); feed.AppendFormat(@"<link href=""{0}"" rel=""self"" type=""application/atom+xml"" />", feedLink); feed.AppendFormat(@"<updated>{0:s}Z</updated>", lastModified); feed.AppendFormat(@"<icon>{0}</icon>", feedIcon); feed.AppendFormat(@"<logo>{0}</logo>", feedLogo); feed.AppendLine(@"<author>"); feed.AppendFormat(@"<name>{0}</name>", author); feed.AppendLine(@"</author>"); feed.AppendFormat(@"<id>urn:uuid:{0}</id>", feedUUID); if (!String.IsNullOrEmpty(blogCategory)) { feed.AppendFormat(@"<category term=""{0}"" />", blogCategory); } } feedInit = true; } if (storeManager.GetTopicInfo(entryTopicName).HasProperty("EntryUUID")) { entryUUID = storeManager.GetTopicProperty(entryTopicName, "EntryUUID").LastValue; } else { entryError = true; entryUUID = System.Guid.NewGuid().ToString(); errEntry.AppendLine("Error: Entry does not have a property 'EntryUUID' or value is empty. A temporary value has been assigned"); } entryLink = BaseUrl + lm.LinkToTopic(entryTopicRev); errEntry.AppendLine("</pre>"); string body = storeManager.GetTopicInfo(entryTopicName).GetProperty("_Body").ToString(); WomDocument xmldoc = new WomDocument(null); xmldoc = _parser.FormatTextFragment(body, entryTopicRev, storeManager, true, 600); xmldoc.ParsedDocument = @"<?xml version=""1.0"" encoding=""utf-8""?> <!DOCTYPE message [ <!ENTITY nbsp "" ""> ]> <div id=""womDocRoot"">" + xmldoc.ParsedDocument + "</div>"; entryContent = _parser.WikiToPresentation(xmldoc.XmlDoc); //string entryContent = Formatter.FormattedTopic(entryTopicRev, OutputFormat.HTML, null, storeManager.Federation, lm); feed.AppendLine(@"<entry>"); feed.AppendFormat(@"<title>{0}</title>", entryTitle); feed.AppendFormat(@"<link href=""{0}"" />", entryLink); feed.AppendFormat(@"<id>urn:uuid:{0}</id>", entryUUID); feed.AppendFormat(@"<updated>{0:s}Z</updated>", lastModified); //feed.AppendLine(@"<content>"); feed.AppendLine(@"<content type=""xhtml"">"); feed.AppendLine(@"<div xmlns=""http://www.w3.org/1999/xhtml"">"); if (feedError) { feed.Append(errFeed.ToString()); } if (entryError) { feed.Append(errEntry.ToString()); } feed.Append(entryContent); feed.AppendLine("</div>"); feed.AppendLine("</content>"); if (storeManager.GetTopicInfo(entryTopicName).HasProperty("Keywords")) { ArrayList keywordsList = storeManager.GetTopicInfo(entryTopicName).KeywordsList; foreach (string keyword in keywordsList) { feed.AppendFormat(@"<category term=""{0}"" />", keyword); } } feed.AppendLine("</entry>"); } else { entryError = true; errEntry.AppendLine("Error: The topic specified in the property 'BlogContents' does not exist."); if (feedError) { feedError = true; if (entryList.Count == 0) { errFeed.AppendLine("Error: Feed does not have a property 'BlogTopics' or that property value is empty"); } if (!String.IsNullOrEmpty(feedTitle)) { feed.AppendFormat(@"<title>{0}</title>", feedTitle); } else { feed.AppendLine("<title>Feed title Unspecified</title>"); errFeed.AppendLine("Error: Feed does not have a property 'Title' or value is empty."); } if (!String.IsNullOrEmpty(author)) { feed.AppendLine(@"<author>"); feed.AppendFormat(@"<name>{0}</name>", author); feed.AppendLine(@"</author>"); } else { feed.AppendLine(@"<author>"); feed.AppendFormat(@"<name>{0}</name>", "Author Unspecified"); feed.AppendLine(@"</author>"); errFeed.AppendLine("Error: Feed does not have a property 'Creator' or value is empty. This may occur as there was no valid entry found to provide a 'Creator' property."); } if (!String.IsNullOrEmpty(feedUUID)) { feed.AppendFormat(@"<id>urn:uuid:{0}</id>", feedUUID); } else { feed.AppendFormat(@"<id>urn:uuid:{0}</id>", System.Guid.NewGuid().ToString()); errFeed.AppendLine("Error: Feed does not have a property 'FeedUUID' or value is empty. A temporary value has been assigned"); } feed.AppendFormat(@"<updated>{0:s}Z</updated>", lastModified); if (!String.IsNullOrEmpty(feedLogo)) { feed.AppendFormat(@"<logo>{0}</logo>", feedLogo); } if (!String.IsNullOrEmpty(feedIcon)) { feed.AppendFormat(@"<icon>{0}</icon>", feedIcon); } if (!String.IsNullOrEmpty(blogCategory)) { feed.AppendFormat(@"<category term=""{0}"" />", blogCategory); } errFeed.AppendLine("</pre>"); } else { feed.AppendFormat(@"<title>{0}</title>", feedTitle); feed.AppendFormat(@"<link href=""{0}"" rel=""self"" type=""application/atom+xml"" />", feedLink); feed.AppendFormat(@"<updated>{0:s}Z</updated>", lastModified); feed.AppendFormat(@"<icon>{0}</icon>", feedIcon); feed.AppendFormat(@"<logo>{0}</logo>", feedLogo); feed.AppendLine(@"<author>"); feed.AppendFormat(@"<name>{0}</name>", author); feed.AppendLine(@"</author>"); feed.AppendFormat(@"<id>urn:uuid:{0}</id>", feedUUID); if (!String.IsNullOrEmpty(blogCategory)) { feed.AppendFormat(@"<category term=""{0}"" />", blogCategory); } } errEntry.AppendLine("</pre>"); feed.AppendLine(@"<entry>"); feed.AppendFormat(@"<title>{0}</title>", entryTitle); feed.AppendFormat(@"<link href=""{0}"" />", entryLink); feed.AppendFormat(@"<id>urn:uuid:{0}</id>", entryUUID); feed.AppendFormat(@"<updated>{0:s}Z</updated>", lastModified); //feed.AppendLine(@"<content>"); feed.AppendLine(@"<content type=""xhtml"">"); feed.AppendLine(@"<div xmlns=""http://www.w3.org/1999/xhtml"">"); if (feedError) { feed.Append(errFeed.ToString()); } if (entryError) { feed.Append(errEntry.ToString()); } feed.Append(entryContent); feed.AppendLine("</div>"); feed.AppendLine("</content>"); if (storeManager.GetTopicInfo(entryTopicName).HasProperty("Keywords")) { ArrayList keywordsList = storeManager.GetTopicInfo(entryTopicName).KeywordsList; foreach (string keyword in keywordsList) { feed.AppendFormat(@"<category term=""{0}"" />", keyword); } } feed.AppendLine("</entry>"); } //end topicVerInfo does not exist } } else { feedError = true; if (entryList.Count == 0) { errFeed.AppendLine("Error: Feed does not have a property 'BlogTopics' or that property value is empty"); } if (!String.IsNullOrEmpty(feedTitle)) { feed.AppendFormat(@"<title>{0}</title>", feedTitle); } else { feed.AppendLine("<title>Feed title Unspecified</title>"); errFeed.AppendLine("Error: Feed does not have a property 'Title' or value is empty."); } if (!String.IsNullOrEmpty(author)) { feed.AppendLine(@"<author>"); feed.AppendFormat(@"<name>{0}</name>", author); feed.AppendLine(@"</author>"); } else { feed.AppendLine(@"<author>"); feed.AppendFormat(@"<name>{0}</name>", "Author Unspecified"); feed.AppendLine(@"</author>"); errFeed.AppendLine("Error: Feed does not have a property 'Creator' or value is empty. This may occur as there was no valid entry found to provide a 'Creator' property."); } if (!String.IsNullOrEmpty(feedUUID)) { feed.AppendFormat(@"<id>urn:uuid:{0}</id>", feedUUID); } else { feed.AppendFormat(@"<id>urn:uuid:{0}</id>", System.Guid.NewGuid().ToString()); errFeed.AppendLine("Error: Feed does not have a property 'FeedUUID' or value is empty. A temporary value has been assigned"); } feed.AppendFormat(@"<updated>{0:s}Z</updated>", System.DateTime.Now.ToUniversalTime()); if (!String.IsNullOrEmpty(feedLogo)) { feed.AppendFormat(@"<logo>{0}</logo>", feedLogo); } if (!String.IsNullOrEmpty(feedIcon)) { feed.AppendFormat(@"<icon>{0}</icon>", feedIcon); } if (!String.IsNullOrEmpty(blogCategory)) { feed.AppendFormat(@"<category term=""{0}"" />", blogCategory); } errFeed.AppendLine("</pre>"); feed.AppendLine(@"<entry>"); feed.AppendLine(@"<title>Error Information</title>"); feed.AppendLine(@"<content type=""xhtml"">"); feed.AppendLine(@"<div xmlns=""http://www.w3.org/1999/xhtml"">"); feed.Append(errFeed.ToString()); feed.AppendLine("</div>"); feed.AppendLine("</content>"); feed.AppendLine(@"</entry>"); } feed.AppendLine("</feed>"); Response.Write(feed.ToString()); }