/// <summary> /// This is overridden to create a target dictionary that utilizes an ESENT database for persistence /// </summary> /// <param name="configuration">The configuration element for the target dictionary</param> /// <returns>A simple dictionary if no <c>cachePath</c> attribute is found or an ESENT backed target /// dictionary if the attribute is found.</returns> public override TargetDictionary CreateTargetDictionary(XPathNavigator configuration) { TargetDictionary td = null; string cachePath = configuration.GetAttribute("cachePath", String.Empty); // If no database path is specified, use the simple target dictionary (i.e. project references) if (String.IsNullOrWhiteSpace(cachePath)) { td = base.CreateTargetDictionary(configuration); } else { try { td = new ESentTargetDictionary(this, configuration); } catch (Exception ex) { this.WriteMessage(MessageLevel.Error, BuildComponentUtilities.GetExceptionMessage(ex)); } } return(td); }
private void AddDatabaseTargets(string file, ReferenceLinkType type) { try { XPathDocument document = new XPathDocument(file); // This will load into the memory, if the database does not // exists... TargetCollectionXmlUtilities.AddTargets(_msdnStorage, document.CreateNavigator(), type); } catch (XmlSchemaException e) { WriteMessage(MessageLevel.Error, String.Format( "The reference targets file '{0}' is not valid. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e))); } catch (XmlException e) { WriteMessage(MessageLevel.Error, String.Format( "The reference targets file '{0}' is not well-formed XML. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e))); } catch (IOException e) { WriteMessage(MessageLevel.Error, String.Format( "An access error occurred while opening the reference targets file '{0}'. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e))); } }
private void ApplyXsd(XPathNavigator documentNavigator, string key) { if (!_isIndexEnabled) { return; } XPathNodeIterator iterator = documentNavigator.Select(_xsdLinksSelector); if (iterator == null || iterator.Count == 0) { return; } XPathNavigator[] navigators = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); string topicType = _indexContent.TopicType; int itemCount = navigators.Length; for (int i = 0; i < itemCount; i++) { XPathNavigator navigator = navigators[i]; string linkUri = navigator.Value; if (!String.IsNullOrEmpty(linkUri)) { IndexItem item = _indexContent[linkUri]; if (item == null) { this.WriteMessage(MessageLevel.Warn, String.Format( "Link value for '{0}' in '{1}' not found", linkUri, key)); } else { XmlWriter writer = navigator.InsertAfter(); writer.WriteStartElement("link", IndexResolver.MamlNamespace); writer.WriteAttributeString("href", IndexResolver.XLinkNamespace, item.Id); if (!String.IsNullOrEmpty(topicType)) { writer.WriteAttributeString("topicType_id", topicType); } writer.WriteString(item.LinkTitle); writer.WriteEndElement(); writer.Close(); } } else { this.WriteMessage(MessageLevel.Warn, String.Format( "A link value in '{0}' is not specified.", key)); } navigator.DeleteSelf(); } }
/// <summary> /// This is overridden to create a target dictionary that utilizes an SQL database for persistence /// </summary> /// <param name="configuration">The configuration element for the target dictionary</param> /// <returns>A simple dictionary if no <c>connectionString</c> attribute is found or a SQL backed target /// dictionary if the attribute is found.</returns> public override TargetDictionary CreateTargetDictionary(XPathNavigator configuration) { TargetDictionary td = null; string connectionString, groupId, attrValue; int frameworkCacheSize, projectCacheSize; bool cacheProject, isProjectData; if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } var parent = configuration.Clone(); parent.MoveToParent(); var cache = parent.SelectSingleNode("sqlCache"); connectionString = cache.GetAttribute("connectionString", String.Empty); attrValue = cache.GetAttribute("frameworkLocalCacheSize", String.Empty); frameworkCacheSize = Convert.ToInt32(attrValue, CultureInfo.InvariantCulture); attrValue = cache.GetAttribute("projectLocalCacheSize", String.Empty); projectCacheSize = Convert.ToInt32(attrValue, CultureInfo.InvariantCulture); attrValue = cache.GetAttribute("cacheProject", String.Empty); cacheProject = Convert.ToBoolean(attrValue, CultureInfo.InvariantCulture); groupId = configuration.GetAttribute("groupId", String.Empty); isProjectData = groupId.StartsWith("Project_", StringComparison.OrdinalIgnoreCase); // If no connection is specified or if it is project data and we aren't caching it, use the simple // target dictionary. if (String.IsNullOrWhiteSpace(connectionString) || (isProjectData && !cacheProject)) { td = base.CreateTargetDictionary(configuration); } else { try { td = new SqlTargetDictionary(this, configuration, connectionString, groupId, isProjectData ? projectCacheSize : frameworkCacheSize, isProjectData); } catch (Exception ex) { this.WriteMessage(MessageLevel.Error, BuildComponentUtilities.GetExceptionMessage(ex)); } } return(td); }
/// <summary> /// This is used to load a set of nested code blocks from external /// files. /// </summary> /// <param name="navCode">The node in which to replace the nested /// code blocks</param> /// <param name="nestedCode">The XPath expression used to locate the /// nested code blocks.</param> /// <returns>The HTML encoded blocks extracted from the files as a /// single code block.</returns> /// <remarks>Only source and region attributes are used. All other /// attributes are obtained from the parent code block. Text nodes /// are created to replace the nested code tags so that any additional /// text in the parent code block is also retained.</remarks> private string LoadNestedCodeBlocks(XPathNavigator navCode, XPathExpression nestedCode) { XPathNavigator[] codeList = BuildComponentUtilities.ConvertNodeIteratorToArray( navCode.Select(nestedCode)); foreach (XPathNavigator codeElement in codeList) { codeElement.ReplaceSelf("\r\n" + this.LoadCodeBlock( ((IHasXmlNode)codeElement).GetNode())); } return(navCode.InnerXml); }
/// <summary> /// This is used to create a <see cref="TargetDictionary"/> used to store reference link targets /// </summary> /// <param name="configuration">The configuration element for the target dictionary</param> /// <returns>A default <see cref="InMemoryTargetDictionary"/> instance containing the reference link /// targets</returns> /// <remarks>This can be overridden in derived classes to provide persistent caches with backing stores /// other than the default <see cref="Dictionary{TKey, TValue}"/></remarks>. public virtual TargetDictionary CreateTargetDictionary(XPathNavigator configuration) { TargetDictionary d = null; try { d = new InMemoryTargetDictionary(this, configuration); } catch (Exception ex) { this.WriteMessage(MessageLevel.Error, BuildComponentUtilities.GetExceptionMessage(ex)); } return(d); }
private void ApplyCodeRefs(XmlDocument document, string key) { XPathNavigator docNavigator = document.CreateNavigator(); XPathNodeIterator iterator = docNavigator.Select(_codeRefSelector); XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); if (arrNavigator == null || arrNavigator.Length == 0) { return; } int itemCount = arrNavigator.Length; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) // not likely! { continue; } string input = navigator.Value; if (Snippet.IsValidReference(input) == false) { this.WriteMessage(MessageLevel.Warn, String.Format( "The code reference '{0}' is not well-formed", input)); navigator.DeleteSelf(); continue; } SnippetInfo[] arrayInfo = Snippet.ParseReference(input); Debug.Assert(arrayInfo != null && arrayInfo.Length != 0); if (arrayInfo.Length == 1) { ApplySnippetInfo(navigator, arrayInfo[0], input); } else { ApplyMultiSnippetInfo(navigator, arrayInfo, input); } } }
private void ProcessConceptualLink(XmlDocument document, string key) { XPathNodeIterator linkIterator = document.CreateNavigator().Select( conceptualLinkExpression); if (linkIterator == null || linkIterator.Count == 0) { return; } XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator); foreach (XPathNavigator linkNode in linkNodes) { this.ProcessConceptualLink(linkNode, key); // delete the original tag linkNode.DeleteSelf(); } }
private void ApplyMath(XPathNavigator docNavigator) { XPathNodeIterator iterator = docNavigator.Select(_mathSelector); if (iterator == null || iterator.Count == 0) { return; } XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); int itemCount = arrNavigator.Length; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) { continue; } string mathFile = navigator.Value; if (String.IsNullOrEmpty(mathFile) == false) { XmlWriter xmlWriter = navigator.InsertAfter(); this.WriteIncludeAttribute(xmlWriter, "src", "mathPath", mathFile); xmlWriter.Close(); navigator.DeleteSelf(); } } }
private void ApplyCode(XPathNavigator docNavigator, XPathExpression codeSelector) { CodeController codeController = CodeController.GetInstance("conceptual"); if (codeController == null || codeController.Mode != CodeHighlightMode.IndirectIris) { return; } XPathNodeIterator iterator = docNavigator.Select(codeSelector); if (iterator == null || iterator.Count == 0) { return; } XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); int itemCount = arrNavigator.Length; string spanNamespace = "http://ddue.schemas.microsoft.com/authoring/2003/5"; string attrName = String.Empty; string attrClass = String.Empty; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) { continue; } string codeLang = null; XPathNodeIterator nodeIterator = navigator.SelectChildren("span", spanNamespace); XPathNavigator placeHolder = null; if (nodeIterator == null || nodeIterator.Count == 0) { continue; } XPathNavigator[] arrSnipNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(nodeIterator); int nodeCount = arrSnipNavigator.Length; XPathNavigator tempHolder = arrSnipNavigator[0]; attrName = tempHolder.GetAttribute("name", String.Empty); attrClass = tempHolder.GetAttribute("class", String.Empty); if (String.Equals(attrName, "SandAssist") && String.Equals(attrClass, "tgtSentence")) { placeHolder = tempHolder; } if (placeHolder != null) { codeLang = placeHolder.Value; placeHolder.DeleteSelf(); } else { base.WriteMessage(MessageLevel.Info, "No code language found."); continue; } Highlighter highlighter = codeController.ApplyLanguage( null, codeLang); if (nodeCount == 1) { string codeText = navigator.Value; if (!String.IsNullOrEmpty(codeText)) { codeText = codeText.Trim(); XmlWriter xmlWriter = navigator.InsertAfter(); if (highlighter != null) { StringReader textReader = new StringReader(codeText); highlighter.Highlight(textReader, xmlWriter); // For the two-part or indirect, we add extra line-break // since this process delete the last extra line. xmlWriter.WriteStartElement("br"); // start - br xmlWriter.WriteEndElement(); // end - br } else { xmlWriter.WriteString(codeText); } xmlWriter.Close(); navigator.DeleteSelf(); } } else { XPathNavigator snipNavigator = null; for (int j = 1; j < nodeCount; j++) { snipNavigator = arrSnipNavigator[j]; if (snipNavigator == null) { base.WriteMessage(MessageLevel.Warn, "Null navigator!"); continue; } attrName = snipNavigator.GetAttribute("name", String.Empty); attrClass = snipNavigator.GetAttribute("class", String.Empty); if (String.Equals(attrName, "SandAssist") == false || String.Equals(attrClass, "srcSentence") == false) { base.WriteMessage(MessageLevel.Warn, attrName); base.WriteMessage(MessageLevel.Warn, attrClass); continue; } int snipIndex = snipNavigator.ValueAsInt; SnippetItem item = codeController[snipIndex]; string codeText = item.Text; if (!String.IsNullOrEmpty(codeText)) { codeText = codeText.Trim(); XmlWriter xmlWriter = snipNavigator.InsertAfter(); if (highlighter != null) { StringReader textReader = new StringReader(codeText); highlighter.Highlight(textReader, xmlWriter); } else { xmlWriter.WriteString(codeText); } xmlWriter.Close(); snipNavigator.DeleteSelf(); } } } } }
/// <summary> /// This is implemented to perform the code colorization. /// </summary> /// <param name="document">The XML document with which to work.</param> /// <param name="key">The key (member name) of the item being /// documented.</param> public override void Apply(XmlDocument document, string key) { XPathNavigator root, navDoc = document.CreateNavigator(); XPathNavigator[] codeList; XPathExpression nestedCode; XmlAttribute attr; XmlNode code, titleDiv, preNode, container, refLink; string language, title, codeBlock; bool nbrLines, outline, seeTags, filter; int tabSize, start, end, blockId = 1, id = 1; // Clear the dictionary colorizedCodeBlocks.Clear(); // Select all code nodes. The location depends on the build type. root = navDoc.SelectSingleNode(referenceRoot); // If not null, it's a reference (API) build. If null, it's // a conceptual build. if (root != null) { codeList = BuildComponentUtilities.ConvertNodeIteratorToArray( root.Select(referenceCode)); nestedCode = nestedRefCode; } else { root = navDoc.SelectSingleNode(conceptualRoot); nestedCode = nestedConceptCode; if (root == null) { base.WriteMessage(MessageLevel.Warn, "Root content node not found. Cannot colorize code."); return; } codeList = BuildComponentUtilities.ConvertNodeIteratorToArray( root.Select(conceptualCode)); } foreach (XPathNavigator navCode in codeList) { code = ((IHasXmlNode)navCode).GetNode(); // If the parent is null, it was a nested node and has already // been handled. if (code.ParentNode == null) { continue; } // Set the defaults language = defaultLanguage; nbrLines = numberLines; outline = outliningEnabled; seeTags = keepSeeTags; filter = languageFilter; tabSize = 0; title = String.Empty; // If there are nested code blocks, load them. Source and // region attributes will be ignored on the parent. All // other attributes will be applied to the combined block of // code. If there are no nested blocks, source and region // will be used to load the code if found. Otherwise, the // existing inner XML is used for the code. if (navCode.SelectSingleNode(nestedCode) != null) { codeBlock = this.LoadNestedCodeBlocks(navCode, nestedCode); } else if (code.Attributes["source"] != null) { codeBlock = this.LoadCodeBlock(code); } else { codeBlock = code.InnerXml; } // Check for option overrides if (code.Attributes["numberLines"] != null) { nbrLines = Convert.ToBoolean(code.Attributes[ "numberLines"].Value, CultureInfo.InvariantCulture); } if (code.Attributes["outlining"] != null) { outline = Convert.ToBoolean(code.Attributes[ "outlining"].Value, CultureInfo.InvariantCulture); } if (code.Attributes["keepSeeTags"] != null) { seeTags = Convert.ToBoolean(code.Attributes[ "keepSeeTags"].Value, CultureInfo.InvariantCulture); } if (code.Attributes["filter"] != null) { filter = Convert.ToBoolean(code.Attributes[ "filter"].Value, CultureInfo.InvariantCulture); } if (code.Attributes["tabSize"] != null) { tabSize = Convert.ToInt32(code.Attributes["tabSize"].Value, CultureInfo.InvariantCulture); } // If either language option is set to "none" or an unknown // language, it just strips excess leading whitespace and // optionally numbers the lines and adds outlining based on // the other settings. if (code.Attributes["lang"] != null) { language = code.Attributes["lang"].Value; } else if (code.Attributes["language"] != null) { language = code.Attributes["language"].Value; } // Use the title if one is supplied. if (code.Attributes["title"] != null) { title = HttpUtility.HtmlEncode(code.Attributes["title"].Value); } // Process the code. The colorizer is built to highlight <pre> tags in an HTML file so we'll // wrap the code in a <pre> tag with the settings. codeBlock = colorizer.ProcessAndHighlightText(String.Format(CultureInfo.InvariantCulture, "<pre lang=\"{0}\" numberLines=\"{1}\" outlining=\"{2}\" " + "keepSeeTags=\"{3}\" tabSize=\"{4}\" {5}>{6}</pre>", language, nbrLines, outline, seeTags, tabSize, (title.Length != 0) ? "title=\"" + title + "\"" : String.Empty, codeBlock)); // Non-breaking spaces are replaced with a space entity. If not, they disappear in the rendered // HTML. Seems to be an XML or XSLT thing. codeBlock = codeBlock.Replace(" ", " "); // Move the title above the code block so that it doesn't interfere with the stuff generated // by the transformation component. The post-transform component will perform some clean-up // to get rid of similar stuff added by it. title = codeBlock.Substring(0, codeBlock.IndexOf("</div>", StringComparison.Ordinal) + 6); codeBlock = codeBlock.Substring(title.Length); titleDiv = document.CreateDocumentFragment(); titleDiv.InnerXml = title; titleDiv = titleDiv.ChildNodes[0]; // Remove the colorizer's <pre> tag. We'll add our own below. start = codeBlock.IndexOf('>') + 1; end = codeBlock.LastIndexOf('<'); // We need to add the xml:space="preserve" attribute on the <pre> element so that MS Help Viewer // doesn't remove significant whitespace between colorized elements. preNode = document.CreateNode(XmlNodeType.Element, "pre", null); attr = document.CreateAttribute("xml:space"); attr.Value = "preserve"; preNode.Attributes.Append(attr); preNode.InnerXml = codeBlock.Substring(start, end - start); // Convert <see> tags to <referenceLink> or <a> tags. We need to do this so that the Resolve // Links component can do its job further down the line. The code blocks are not present when // the transformations run so that the colorized HTML doesn't get stripped out in conceptual // builds. This could be redone to use a <markup> element if the Sandcastle transformations // ever support it natively. foreach (XmlNode seeTag in preNode.SelectNodes("//see")) { if (seeTag.Attributes["cref"] != null) { refLink = document.CreateElement("referenceLink"); } else { refLink = document.CreateElement("a"); } foreach (XmlAttribute seeAttr in seeTag.Attributes) { if (seeAttr.Name == "cref") { attr = document.CreateAttribute("target"); } else { attr = (XmlAttribute)seeAttr.Clone(); } attr.Value = seeAttr.Value; refLink.Attributes.Append(attr); } if (seeTag.HasChildNodes) { refLink.InnerXml = seeTag.InnerXml; } seeTag.ParentNode.ReplaceChild(refLink, seeTag); } // The <span> tags cannot be self-closing if empty. The colorizer renders them correctly but // when written out as XML, they get converted to self-closing tags which breaks them. To fix // them, store an empty string in each empty span so that it renders as an opening and closing // tag. Note that if null, InnerText returns an empty string by default. As such, this looks // redundant but it really isn't (see note above). foreach (XmlNode span in preNode.SelectNodes("//span")) { if (span.InnerText.Length == 0) { span.InnerText = String.Empty; } } // Add language filter stuff if needed or just the title if there is one and we aren't // using the language filter. if (filter) { // If necessary, map the language ID to one we will recognize language = language.ToLower(CultureInfo.InvariantCulture); if (colorizer.AlternateIds.ContainsKey(language)) { language = colorizer.AlternateIds[language]; } container = this.AddLanguageFilter(titleDiv, preNode, language, blockId++); } else { container = document.CreateNode(XmlNodeType.Element, "span", null); container.AppendChild(titleDiv); container.AppendChild(preNode); } // Replace the code with a placeholder ID. The post-transform // component will relace it with the code from the container. code.InnerXml = "@@_SHFB_" + id.ToString(CultureInfo.InvariantCulture); // Add the container to the code block dictionary colorizedCodeBlocks.Add(code.InnerXml, container); id++; } }
private void ApplyTokens(XPathNavigator documentNavigator) { XPathNodeIterator iterator = documentNavigator.Select(_tokensSelector); if (iterator == null || iterator.Count == 0) { return; } XPathNavigator[] navigators = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); int itemCount = navigators.Length; for (int i = 0; i < itemCount; i++) { XPathNavigator navigator = navigators[i]; string tokenText = navigator.Value; if (tokenText != null) { tokenText = tokenText.Trim(); } if (!String.IsNullOrEmpty(tokenText)) { if (tokenText.Equals("lineBreak", StringComparison.OrdinalIgnoreCase)) { XmlWriter writer = navigator.InsertAfter(); writer.WriteStartElement("br"); writer.WriteEndElement(); writer.Close(); } else if (tokenText.Equals("iconColumn", StringComparison.OrdinalIgnoreCase)) { XPathNavigator tableNode = navigator.Clone(); while (tableNode.MoveToParent()) { if (String.Equals(tableNode.LocalName, "table", StringComparison.OrdinalIgnoreCase) || String.Equals(tableNode.LocalName, "div", StringComparison.OrdinalIgnoreCase)) { break; } } if (String.Equals(tableNode.LocalName, "table", StringComparison.OrdinalIgnoreCase)) { XmlWriter writer = tableNode.PrependChild(); writer.WriteStartElement("col"); writer.WriteAttributeString("style", "width:24px"); writer.WriteEndElement(); writer.Close(); } } } navigator.DeleteSelf(); } }
public override void Apply(XmlDocument document, string key) { // find links XPathNodeIterator linkIterator = document.CreateNavigator().Select(conceptualLinks); if (linkIterator == null || linkIterator.Count == 0) { return; } // copy them to an array, because enumerating through an XPathNodeIterator // fails when the nodes in it are altered XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator); foreach (XPathNavigator linkNode in linkNodes) { ConceptualLinkInfo link = ConceptualLinkInfo.Create(linkNode); // determine url, text, and link type string url = null; string text = null; ConceptualLinkType type = ConceptualLinkType.None; bool isValidLink = validGuid.IsMatch(link.Target); if (isValidLink) { // a valid link; try to fetch target info TargetInfo target = _targetController[link.Target]; if (target == null) { // no target found; issue warning, set link style to none, and text to in-source fall-back //type = LinkType.None; //type = LinkType.Index; text = BrokenLinkDisplayText(link.Target, link.Text); WriteMessage(MessageLevel.Warn, String.Format( "Unknown conceptual link target '{0}'.", link.Target)); } else { // found target; get url, text, and type from stored info url = target.Url; if (link.IsAnchored) { url += link.Anchor; } if (_showText && !String.IsNullOrEmpty(link.Text)) { text = link.Text; } else { text = target.Text; } type = target.Type; } } else { // not a valid link; issue warning, set link style to none, and text to invalid target //type = LinkType.None; text = BrokenLinkDisplayText(link.Target, link.Text); WriteMessage(MessageLevel.Warn, String.Format( "Invalid conceptual link target '{0}'.", link.Target)); } // Override the type, if valid... if (_baseLinkType != ConceptualLinkType.Null && type != ConceptualLinkType.None) { type = _baseLinkType; } // write opening link tag and target info XmlWriter writer = linkNode.InsertAfter(); switch (type) { case ConceptualLinkType.None: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "nolink"); break; case ConceptualLinkType.Local: writer.WriteStartElement("a"); writer.WriteAttributeString("href", url); break; case ConceptualLinkType.Index: writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp"); writer.WriteAttributeString("keywords", link.Target.ToLower()); writer.WriteAttributeString("tabindex", "0"); break; case ConceptualLinkType.Id: string xhelp = String.Format("ms-xhelp://?Id={0}", link.Target); writer.WriteStartElement("a"); writer.WriteAttributeString("href", xhelp); break; } // write the link text writer.WriteString(text); // write the closing link tag writer.WriteEndElement(); writer.Close(); // delete the original tag linkNode.DeleteSelf(); } }
private void ApplyMath(XmlDocument document) { _pageCount++; if (_numberByPage) { _mathNumber = 1; } XPathNavigator docNavigator = document.CreateNavigator(); XPathNodeIterator iterator = docNavigator.Select(_xpathSelector); if (iterator == null || iterator.Count == 0) { return; } XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); int itemCount = arrNavigator.Length; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) { continue; } string mathTitle = null; bool hasTitle = false; XPathNavigator titleItem = navigator.SelectSingleNode("title"); if (titleItem != null) { mathTitle = titleItem.Value; titleItem.DeleteSelf(); hasTitle = !String.IsNullOrEmpty(mathTitle); } string mathInfo = navigator.GetAttribute("address", String.Empty); string mathText = navigator.Value; if (String.IsNullOrEmpty(mathText)) { continue; } mathText = mathText.Trim(); _isNumbered = true; string mediaFormat = FormatEquation(mathInfo, mathText); if (String.IsNullOrEmpty(mediaFormat) == false) { XmlWriter xmlWriter = navigator.InsertAfter(); // For the inline math... if (_isInline) { xmlWriter.WriteStartElement("span"); // start - span xmlWriter.WriteAttributeString("class", _mathClass); xmlWriter.WriteStartElement("img"); // start - img xmlWriter.WriteAttributeString("alt", String.Empty); //xmlWriter.WriteAttributeString("src", mediaFormat); xmlWriter.WriteStartElement("span"); xmlWriter.WriteAttributeString("name", "SandMath"); xmlWriter.WriteAttributeString("class", "tgtSentence"); xmlWriter.WriteString(mediaFormat); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); // end - img xmlWriter.WriteEndElement(); // end - span } else { // For the displayed math... xmlWriter.WriteStartElement("div"); // start - div xmlWriter.WriteAttributeString("class", MathController.MathDiv); if (_numberShow && _isNumbered) { xmlWriter.WriteStartElement("table"); // start - table xmlWriter.WriteAttributeString("class", MathController.MathTable); if (hasTitle) { xmlWriter.WriteStartElement("tr"); // start - tr xmlWriter.WriteStartElement("th"); // start - th xmlWriter.WriteAttributeString("colspan", "2"); xmlWriter.WriteString(mathTitle); xmlWriter.WriteEndElement(); // end - th xmlWriter.WriteEndElement(); // end - tr } xmlWriter.WriteStartElement("tr"); // start - tr xmlWriter.WriteAttributeString("class", MathController.MathRow); xmlWriter.WriteStartElement("td"); // start - td xmlWriter.WriteAttributeString("class", MathController.MathLeft); xmlWriter.WriteAttributeString("style", "background-color:white;border:0"); xmlWriter.WriteStartElement("img"); xmlWriter.WriteAttributeString("class", _mathClass); xmlWriter.WriteAttributeString("alt", String.Empty); //xmlWriter.WriteAttributeString("src", mediaFormat); xmlWriter.WriteStartElement("span"); xmlWriter.WriteAttributeString("name", "SandMath"); xmlWriter.WriteAttributeString("class", "tgtSentence"); xmlWriter.WriteString(mediaFormat); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); // end - tr xmlWriter.WriteStartElement("td"); // start - td xmlWriter.WriteAttributeString("class", MathController.MathRight); xmlWriter.WriteAttributeString("style", "background-color:white;border:0"); if (_numberIncludesPage) { xmlWriter.WriteString(String.Format(_numberFormat, _pageCount, _mathNumber)); } else { xmlWriter.WriteString(String.Format(_numberFormat, _mathNumber)); } xmlWriter.WriteEndElement(); // end - tr xmlWriter.WriteEndElement(); // end - tr xmlWriter.WriteEndElement(); // end - table } else { if (hasTitle) { xmlWriter.WriteStartElement("table"); // start - table xmlWriter.WriteAttributeString("class", MathController.MathTable); if (String.IsNullOrEmpty(mathTitle) == false) { xmlWriter.WriteStartElement("tr"); // start - tr xmlWriter.WriteStartElement("th"); // start - th xmlWriter.WriteString(mathTitle); xmlWriter.WriteEndElement(); // end - th xmlWriter.WriteEndElement(); // end - tr } xmlWriter.WriteStartElement("tr"); // start - tr xmlWriter.WriteStartElement("td"); // start - td } else { xmlWriter.WriteStartElement("div"); // start - div (mathHana) xmlWriter.WriteAttributeString("class", "mathHana"); } xmlWriter.WriteStartElement("img"); xmlWriter.WriteAttributeString("class", MathController.MathImage); xmlWriter.WriteAttributeString("alt", String.Empty); //xmlWriter.WriteAttributeString("src", mediaFormat); xmlWriter.WriteStartElement("span"); xmlWriter.WriteAttributeString("name", "SandMath"); xmlWriter.WriteAttributeString("class", "tgtSentence"); xmlWriter.WriteString(mediaFormat); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); if (hasTitle) { xmlWriter.WriteEndElement(); // end - td xmlWriter.WriteEndElement(); // end - tr xmlWriter.WriteEndElement(); // end - table } else { xmlWriter.WriteEndElement(); //end - div (mathHana) } } xmlWriter.WriteEndElement(); // end - div } xmlWriter.Close(); if (_isNumbered) { _mathNumber++; } navigator.DeleteSelf(); } else { this.WriteMessage(MessageLevel.Warn, String.Format("Math item not valid - {0}", mathInfo)); } } }
private void ProcessReferenceLink(XmlDocument document, string key) { XPathNodeIterator linkIterator = document.CreateNavigator().Select( referenceLinkExpression); if (linkIterator == null || linkIterator.Count == 0) { return; } XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator); foreach (XPathNavigator linkNode in linkNodes) { // extract link information ReferenceLinkInfo link = ReferenceLinkInfo.Create(linkNode); if (link == null) { this.WriteMessage(MessageLevel.Warn, "Invalid referenceLink element."); #if DEBUG this.WriteMessage(MessageLevel.Warn, linkNode.OuterXml); #endif } else { // determine target, link type, and display options string targetId = link.Target; ReferenceLinkDisplayOptions options = link.DisplayOptions; ReferenceLinkType type = ReferenceLinkType.None; Target target = _targets[targetId]; if (target == null) { if (_hasTopicLinks && _targetController[targetId] != null) { this.ProcessConceptualLink(linkNode, key); // delete the original tag linkNode.DeleteSelf(); continue; } else { // no such target known; set link type to none and warn type = ReferenceLinkType.None; this.WriteMessage(MessageLevel.Warn, String.Format( "Unknown reference link target '{0}'.", targetId)); } } else { // if overload is preferred and found, change targetId and make link options hide parameters if (link.PreferOverload) { bool isConversionOperator = false; TargetType targetType = target.TargetType; MemberTarget member = null; if (targetType == TargetType.Method) { MethodTarget method = (MethodTarget)target; isConversionOperator = method.ConversionOperator; member = method; // a method is a member... } else if (targetType == TargetType.Member || targetType == TargetType.Constructor || targetType == TargetType.Procedure || targetType == TargetType.Event || targetType == TargetType.Property) { member = (MemberTarget)target; } // if conversion operator is found, always link to individual topic. if ((member != null) && (!String.IsNullOrEmpty(member.OverloadId)) && !isConversionOperator) { Target overloadTarget = _targets[member.OverloadId]; if (overloadTarget != null) { target = overloadTarget; targetId = overloadTarget.Id; } } // if individual conversion operator is found, always display parameters. if (isConversionOperator && member != null && (!string.IsNullOrEmpty(member.OverloadId))) { options = options | ReferenceLinkDisplayOptions.ShowParameters; } else { options = options & ~ReferenceLinkDisplayOptions.ShowParameters; } } // get stored link type type = _targets.RecentLinkTypeIsMsdn ? _targets.RecentLinkType : target.LinkType; // if link type is local or index, determine which if (type == ReferenceLinkType.LocalOrIndex) { if ((key != null) && _targets.Contains(key) && (target.Container == _targets[key].Container)) { type = ReferenceLinkType.Local; } else { type = ReferenceLinkType.Index; } } } // links to this page are not live if (targetId == key) { type = ReferenceLinkType.Self; } else if ((target != null) && (key != null) && _targets.Contains(key) && (target.File == _targets[key].File)) { type = ReferenceLinkType.Self; } // get msdn endpoint, if needed string msdnUrl = null; if (type == ReferenceLinkType.Msdn) { if ((_msdnResolver == null) || (_msdnResolver.IsDisabled)) { // no msdn resolver } else { msdnUrl = _msdnResolver[targetId]; if (String.IsNullOrEmpty(msdnUrl)) { WriteMessage(MessageLevel.Warn, String.Format( "MSDN URL not found for target '{0}'.", targetId)); } } if (String.IsNullOrEmpty(msdnUrl)) { type = ReferenceLinkType.None; } } // write opening link tag and target info XmlWriter writer = linkNode.InsertAfter(); switch (type) { case ReferenceLinkType.None: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "nolink"); break; case ReferenceLinkType.Self: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "selflink"); break; case ReferenceLinkType.Local: // format link with prefix and/or postfix string href = String.Format(_hrefFormat, target.File); // make link relative, if we have a baseUrl if (_baseUrl != null) { href = BuildComponentUtilities.GetRelativePath(href, BuildComponentUtilities.EvalXPathExpr(document, _baseUrl, "key", key)); } writer.WriteStartElement("a"); writer.WriteAttributeString("href", href); break; case ReferenceLinkType.Index: writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp"); writer.WriteAttributeString("keywords", targetId); writer.WriteAttributeString("tabindex", "0"); break; case ReferenceLinkType.Msdn: writer.WriteStartElement("a"); writer.WriteAttributeString("href", msdnUrl); writer.WriteAttributeString("target", _linkTarget); break; case ReferenceLinkType.Id: string xhelp = String.Format("ms-xhelp://?Id={0}", targetId); xhelp = xhelp.Replace("#", "%23"); writer.WriteStartElement("a"); writer.WriteAttributeString("href", xhelp); break; } // write the link text if (String.IsNullOrEmpty(link.DisplayTarget)) { if (link.Contents == null) { if (target != null) { _linkResolver.WriteTarget(target, options, writer); } else { Reference reference = ReferenceTextUtilities.CreateReference(targetId); if (reference.ReferenceType == ReferenceType.Invalid) { WriteMessage(MessageLevel.Warn, String.Format( "Invalid reference link target '{0}'.", targetId)); } _linkResolver.WriteReference(reference, options, writer); } } else { // write contents to writer link.Contents.WriteSubtree(writer); } } else { if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null)) { // Use the contents as an XML representation of the display target Reference reference = TargetCollectionXmlUtilities.CreateReference(link.Contents); _linkResolver.WriteReference(reference, options, writer); } if ((String.Compare(link.DisplayTarget, "format", true) == 0) && (link.Contents != null)) { // Use the contents as a format string for the display target string format = link.Contents.OuterXml; string input = null; StringWriter textStore = new StringWriter(); try { XmlWriter xmlStore = XmlWriter.Create(textStore, _writerSettings); try { if (target != null) { _linkResolver.WriteTarget(target, options, xmlStore); } else { Reference reference = ReferenceTextUtilities.CreateReference(targetId); _linkResolver.WriteReference(reference, options, xmlStore); } } finally { xmlStore.Close(); } input = textStore.ToString(); } finally { textStore.Close(); } string output = String.Format(format, input); XmlDocumentFragment fragment = document.CreateDocumentFragment(); fragment.InnerXml = output; fragment.WriteTo(writer); //writer.WriteRaw(output); } else if ((String.Compare(link.DisplayTarget, "extension", true) == 0) && (link.Contents != null)) { Reference extMethodReference = TargetCollectionXmlUtilities.CreateExtensionMethodReference(link.Contents); _linkResolver.WriteReference(extMethodReference, options, writer); } else { // Use the display target value as a CER for the display target ReferenceTextUtilities.SetGenericContext(key); Reference reference = ReferenceTextUtilities.CreateReference(link.DisplayTarget); _linkResolver.WriteReference(reference, options, writer); } } // write the closing link tag writer.WriteEndElement(); writer.Close(); } // delete the original tag linkNode.DeleteSelf(); } }
private void ApplyMath(XPathNavigator docNavigator) { XPathNodeIterator iterator = docNavigator.Select(_mathSelector); if (iterator == null || iterator.Count == 0) { return; } BuildComponentStyle builderStyle = this.Style; XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); int itemCount = arrNavigator.Length; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) { continue; } string artTarget = navigator.GetAttribute("target", String.Empty); if (String.IsNullOrEmpty(artTarget)) { if (navigator.MoveToParent()) { navigator.DeleteSelf(); } this.WriteMessage(MessageLevel.Warn, "The equation media link target is not defined."); continue; } int separator = artTarget.IndexOf(':'); if (separator <= 0 || separator == (artTarget.Length - 1)) { if (navigator.MoveToParent()) { navigator.DeleteSelf(); } this.WriteMessage(MessageLevel.Warn, "The equation media link target is not valid."); continue; } string mathFormat = artTarget.Substring(0, separator); string mathFile = artTarget.Substring(separator + 1); if (String.IsNullOrEmpty(mathFormat) || String.IsNullOrEmpty(mathFile)) { if (navigator.MoveToParent()) { navigator.DeleteSelf(); } this.WriteMessage(MessageLevel.Warn, "The equation media link target is not valid."); continue; } string[] formatLines = mathFormat.Split(new char[] { '|' }); int formatCount = formatLines.Length; if (formatCount == 2) { navigator.MoveToParent(); XmlWriter xmlWriter = navigator.InsertAfter(); xmlWriter.WriteStartElement("div"); xmlWriter.WriteAttributeString("class", MathController.MathNone); xmlWriter.WriteStartElement("p"); xmlWriter.WriteStartElement("img"); xmlWriter.WriteAttributeString("class", formatLines[1]); xmlWriter.WriteAttributeString("alt", String.Empty); //xmlWriter.WriteAttributeString("src", mathFile); this.WriteIncludeAttribute(xmlWriter, "src", "mathPath", mathFile); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.Close(); navigator.DeleteSelf(); } else if (formatCount == 3) { XmlWriter xmlWriter = null; int equationNum = Convert.ToInt32(formatLines[2]); if (equationNum == 0) // for inline-equations { xmlWriter = navigator.InsertAfter(); xmlWriter.WriteStartElement("span"); // start - span xmlWriter.WriteAttributeString("class", formatLines[1]); xmlWriter.WriteStartElement("img"); // start - img xmlWriter.WriteAttributeString("alt", String.Empty); //xmlWriter.WriteAttributeString("src", mathFile); this.WriteIncludeAttribute(xmlWriter, "src", "mathPath", mathFile); xmlWriter.WriteEndElement(); // end - img xmlWriter.WriteEndElement(); // end - span } else { navigator.MoveToParent(); xmlWriter = navigator.InsertAfter(); xmlWriter.WriteStartElement("div"); // start - div //xmlWriter.WriteAttributeString("align", "center"); xmlWriter.WriteAttributeString("class", MathController.MathDiv); //xmlWriter.WriteStartElement("p"); // start - p if (_mathNumber && equationNum > 0) { xmlWriter.WriteStartElement("table"); // start - table xmlWriter.WriteAttributeString("class", MathController.MathTable); xmlWriter.WriteStartElement("tr"); // start - tr xmlWriter.WriteAttributeString("class", MathController.MathRow); xmlWriter.WriteStartElement("td"); // start - td xmlWriter.WriteAttributeString("class", MathController.MathLeft); xmlWriter.WriteAttributeString("style", "background-color:white;border:0"); xmlWriter.WriteStartElement("img"); xmlWriter.WriteAttributeString("class", formatLines[1]); xmlWriter.WriteAttributeString("alt", String.Empty); //xmlWriter.WriteAttributeString("src", mathFile); this.WriteIncludeAttribute(xmlWriter, "src", "mathPath", mathFile); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); // end - tr xmlWriter.WriteStartElement("td"); // start - td xmlWriter.WriteAttributeString("class", MathController.MathRight); xmlWriter.WriteAttributeString("style", "background-color:white;border:0"); if (_mathNumIncludePage) { xmlWriter.WriteString(String.Format(_mathNumFormat, _pageCount, equationNum)); } else { xmlWriter.WriteString(String.Format(_mathNumFormat, equationNum)); } xmlWriter.WriteEndElement(); // end - tr xmlWriter.WriteEndElement(); // end - tr xmlWriter.WriteEndElement(); // end - table } else { if (builderStyle == BuildComponentStyle.Hana) { xmlWriter.WriteStartElement("div"); xmlWriter.WriteAttributeString("class", "mathHana"); } xmlWriter.WriteStartElement("img"); xmlWriter.WriteAttributeString("class", formatLines[1]); xmlWriter.WriteAttributeString("alt", String.Empty); //xmlWriter.WriteAttributeString("src", mathFile); this.WriteIncludeAttribute(xmlWriter, "src", "mathPath", mathFile); xmlWriter.WriteEndElement(); if (builderStyle == BuildComponentStyle.Hana) { xmlWriter.WriteEndElement(); } } //xmlWriter.WriteEndElement(); // end - p xmlWriter.WriteEndElement(); // end - div } if (xmlWriter != null) { xmlWriter.Close(); navigator.DeleteSelf(); } } else { if (navigator.MoveToParent()) { navigator.DeleteSelf(); } this.WriteMessage(MessageLevel.Warn, "The equation styling text is not valid."); continue; } } }
private void InsertVideo(XmlDocument document, string key, XPathNavigator artLink, MediaTarget target) { // evaluate the path string path = document.CreateNavigator().Evaluate( target.OutputXPath).ToString(); if (target.baseOutputPath != null) { path = Path.Combine(target.baseOutputPath, path); } string outputPath = Path.Combine(path, target.Name); string targetDirectory = Path.GetDirectoryName(outputPath); if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } if (File.Exists(target.InputPath)) { if (File.Exists(outputPath)) { File.SetAttributes(outputPath, FileAttributes.Normal); } File.Copy(target.InputPath, outputPath, true); } else { this.WriteMessage(MessageLevel.Warn, String.Format( "The file '{0}' for the art target '{1}' was not found.", target.InputPath, target.Id)); } XmlWriter writer = artLink.InsertAfter(); writer.WriteStartElement("img"); if (target.Text != null) { writer.WriteAttributeString("alt", target.Text); } if (target.FormatXPath == null) { writer.WriteAttributeString("src", target.LinkPath); } else { // WebDocs way, which uses the 'format' xpath expression // to calculate the target path and then makes it // relative to the current page if the 'relative-to' // attribute is used. string src = BuildComponentUtilities.EvalXPathExpr( document, target.FormatXPath, "key", Path.GetFileName(outputPath)); if (target.RelativeToXPath != null) { src = BuildComponentUtilities.GetRelativePath(src, BuildComponentUtilities.EvalXPathExpr(document, target.RelativeToXPath, "key", key)); } writer.WriteAttributeString("src", src); } writer.WriteEndElement(); writer.Close(); artLink.DeleteSelf(); }
private void ApplyFlash(XmlDocument document, string key, XPathNavigator docNavigator) { XPathNavigator navigator = docNavigator.SelectSingleNode(_headSelector); if (navigator == null) { return; } XmlWriter writer = navigator.AppendChild(); // 1. We include the script, SWFObject, to handle the Flash... this.WriteScript(writer, "swfobject.js"); // Just a quick drop on this opportunity... if (_silverlightInsertScript) { this.WriteScript(writer, "Silverlight.js"); _silverlightInsertScript = false; } // Write the executable script code... StringBuilder builder = new StringBuilder(); builder.AppendLine(); int itemCount = _flashTargets.Count; for (int i = 0; i < itemCount; i++) { MediaTarget target = _flashTargets[i]; string src = null; if (target.FormatXPath == null) { src = target.LinkPath; } else { // evaluate the path string path = document.CreateNavigator().Evaluate( target.OutputXPath).ToString(); if (target.baseOutputPath != null) { path = Path.Combine(target.baseOutputPath, path); } string outputPath = Path.Combine(path, target.Name); // WebDocs way, which uses the 'format' xpath expression // to calculate the target path and then makes it // relative to the current page if the 'relative-to' // attribute is used. src = BuildComponentUtilities.EvalXPathExpr( document, target.FormatXPath, "key", Path.GetFileName(outputPath)); if (target.RelativeToXPath != null) { src = BuildComponentUtilities.GetRelativePath(src, BuildComponentUtilities.EvalXPathExpr(document, target.RelativeToXPath, "key", key)); } } int width = target.Width; if (width <= 0) { width = 560; } int height = target.Height; if (height <= 0) { height = 345; } builder.AppendFormat( "swfobject.embedSWF(\"{0}\", \"{1}\", \"{2}\", \"{3}\", \"9.0.0\");", src, target.Id, width, height); if (itemCount > 1 && i < (itemCount - 1)) { builder.AppendLine(); } } //<script type="text/javascript"> //swfobject.embedSWF("test.swf", "myContent", "300", "120", "9.0.0", "expressInstall.swf"); //</script> if (builder.Length != 0) { writer.WriteStartElement("script"); writer.WriteAttributeString("type", "text/javascript"); writer.WriteString(builder.ToString()); writer.WriteFullEndElement(); } writer.Close(); }
private void ApplyCodes(XmlDocument document, string key) { CodeHighlightMode highlightMode = this.Mode; CodeController codeController = CodeController.GetInstance("conceptual"); if (codeController == null) { return; } XPathNavigator docNavigator = document.CreateNavigator(); XPathNodeIterator iterator = docNavigator.Select(_codeSelector); XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); if (arrNavigator == null || arrNavigator.Length == 0) { return; } int tabSize = this.TabSize; int itemCount = arrNavigator.Length; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) // not likely! { continue; } string codeText = navigator.Value; if (String.IsNullOrEmpty(codeText)) { this.WriteMessage(MessageLevel.Warn, "CodeHighlightComponent: source code is null/empty."); continue; } StringBuilder inputText = CodeFormatter.StripLeadingSpaces( codeText, tabSize); if (inputText == null || inputText.Length == 0) { continue; } string codeLang = navigator.GetAttribute("language", String.Empty); if (String.IsNullOrEmpty(codeLang)) { navigator.SetValue(inputText.ToString()); continue; } inputText.Replace("<codeFeaturedElement>", String.Empty); inputText.Replace("<codeFeaturedElement/>", String.Empty); inputText.Replace("<placeholder>", String.Empty); inputText.Replace("<placeholder/>", String.Empty); inputText.Replace("<comment>", String.Empty); inputText.Replace("<comment/>", String.Empty); inputText.Replace("<legacyItalic>", String.Empty); inputText.Replace("<legacyItalic/>", String.Empty); _codeCount++; XmlWriter xmlWriter = navigator.InsertAfter(); xmlWriter.WriteStartElement("snippets"); // start - snippets xmlWriter.WriteAttributeString("reference", _codeCount.ToString()); xmlWriter.WriteStartElement("snippet"); // start - snippet Highlighter highlighter = codeController.ApplyLanguage( xmlWriter, codeLang); if (highlightMode == CodeHighlightMode.None) { xmlWriter.WriteString(inputText.ToString()); } else if (highlightMode == CodeHighlightMode.IndirectIris) { xmlWriter.WriteStartElement("span"); xmlWriter.WriteAttributeString("name", "SandAssist"); xmlWriter.WriteAttributeString("class", "tgtSentence"); xmlWriter.WriteString(codeLang); xmlWriter.WriteEndElement(); xmlWriter.WriteString(inputText.ToString()); } else { if (highlighter != null) { if (highlightMode == CodeHighlightMode.DirectIris) { xmlWriter.WriteStartElement("markup"); // start - markup } StringReader textReader = new StringReader( inputText.ToString()); highlighter.Highlight(textReader, xmlWriter); if (highlightMode == CodeHighlightMode.DirectIris) { xmlWriter.WriteEndElement(); // end - markup } } else { xmlWriter.WriteString(inputText.ToString()); } } xmlWriter.WriteEndElement(); // end - snippet xmlWriter.WriteEndElement(); // end - snippets xmlWriter.Close(); navigator.DeleteSelf(); } }
private void WriteImage(XmlDocument document, string key, string outputPath, XmlWriter writer, MediaTarget target) { writer.WriteStartElement("img"); // start: img if (target.Text != null) { writer.WriteAttributeString("alt", target.Text); } if (target.HasMap) { writer.WriteAttributeString("usemap", target.UseMap); // Prevent IE:6-8, Firefox:1-3 from drawing border... writer.WriteAttributeString("border", "0"); } if (target.FormatXPath == null) { if (_useInclude) { writer.WriteStartElement("span"); writer.WriteAttributeString("name", "SandMedia"); writer.WriteAttributeString("class", "tgtSentence"); writer.WriteString(target.Name); writer.WriteEndElement(); } else { writer.WriteAttributeString("src", target.LinkPath); } } else { // WebDocs way, which uses the 'format' xpath expression // to calculate the target path and then makes it // relative to the current page if the 'relative-to' // attribute is used. string src = BuildComponentUtilities.EvalXPathExpr( document, target.FormatXPath, "key", Path.GetFileName(outputPath)); if (target.RelativeToXPath != null) { src = BuildComponentUtilities.GetRelativePath(src, BuildComponentUtilities.EvalXPathExpr(document, target.RelativeToXPath, "key", key)); } if (_useInclude) { writer.WriteStartElement("span"); writer.WriteAttributeString("name", "SandMedia"); writer.WriteAttributeString("class", "tgtSentence"); writer.WriteString(src); writer.WriteEndElement(); } else { writer.WriteAttributeString("src", src); } } writer.WriteEndElement(); // end: img if (target.HasMap) { StringReader textReader = new StringReader(target.Map); using (XmlReader xmlReader = XmlReader.Create(textReader)) { writer.WriteNode(xmlReader, true); } textReader.Close(); } }
private void ApplyCode(XPathNavigator docNavigator) { CodeController codeController = CodeController.GetInstance("reference"); if (codeController == null || codeController.Mode != CodeHighlightMode.IndirectIris) { return; } XPathNodeIterator iterator = docNavigator.Select(_codeSelector); if (iterator == null || iterator.Count == 0) { return; } XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); int itemCount = arrNavigator.Length; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) { continue; } string codeLang = navigator.Value; if (navigator.MoveToParent() && String.Equals(navigator.Name, "pre")) { XPathNavigator placeHolder = navigator.SelectSingleNode( "span[@name='SandAssist' and @class='tgtSentence']"); if (placeHolder != null) { placeHolder.DeleteSelf(); } Highlighter highlighter = codeController.ApplyLanguage( null, codeLang); XPathNodeIterator snipIterator = navigator.Select( "span[@name='SandAssist' and @class='srcSentence']"); XPathNavigator[] arrSnipNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(snipIterator); if (arrSnipNavigator == null || arrSnipNavigator.Length == 0) { string codeText = navigator.Value; if (String.IsNullOrEmpty(codeText) == false) { if (highlighter != null) { XmlWriter xmlWriter = navigator.InsertAfter(); StringReader textReader = new StringReader(codeText); highlighter.Highlight(textReader, xmlWriter); // For the two-part or indirect, we add extra line-break // since this process delete the last extra line. xmlWriter.WriteStartElement("br"); // start - br xmlWriter.WriteEndElement(); // end - br xmlWriter.Close(); navigator.DeleteSelf(); } } } else { XPathNavigator snipNavigator = null; int snipCount = arrSnipNavigator.Length; for (int j = 0; j < snipCount; j++) { snipNavigator = arrSnipNavigator[j]; if (snipNavigator == null) { continue; } int snipIndex = snipNavigator.ValueAsInt; SnippetItem item = codeController[snipIndex]; if (item == null) { this.WriteMessage(MessageLevel.Warn, "A code snippet specified could not be found. See next message for details."); snipNavigator.DeleteSelf(); continue; } string codeText = item.Text; if (String.IsNullOrEmpty(codeText) == false) { XmlWriter xmlWriter = snipNavigator.InsertAfter(); if (highlighter != null) { StringReader textReader = new StringReader(codeText); highlighter.Highlight(textReader, xmlWriter); } else { xmlWriter.WriteString(codeText); } xmlWriter.Close(); snipNavigator.DeleteSelf(); } } } } } }
private void InsertSilverlight(XmlDocument document, string key, XPathNavigator artLink, MediaTarget target) { if (String.IsNullOrEmpty(_silverlightError)) { _silverlightError = Resources.SilverlightError; } // evaluate the path string path = document.CreateNavigator().Evaluate( target.OutputXPath).ToString(); if (target.baseOutputPath != null) { path = Path.Combine(target.baseOutputPath, path); } string outputPath = Path.Combine(path, target.Name); string targetDirectory = Path.GetDirectoryName(outputPath); if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } string minRuntimeVersion = "2.0.31005.0"; if (File.Exists(target.InputPath)) { if (File.Exists(outputPath)) { File.SetAttributes(outputPath, FileAttributes.Normal); } File.Copy(target.InputPath, outputPath, true); // We try to extract the runtime version from the module... MemoryStream stream = new MemoryStream(); using (ZipFile zip = ZipFile.Read(target.InputPath)) { ZipEntry e = zip["AppManifest.xaml"]; if (e != null) { e.Extract(stream); } } if (stream.Length != 0) { XmlReaderSettings settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; stream.Seek(0, SeekOrigin.Begin); XmlReader reader = XmlReader.Create(stream, settings); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && String.Equals(reader.Name, "Deployment", StringComparison.OrdinalIgnoreCase)) { minRuntimeVersion = reader.GetAttribute("RuntimeVersion"); if (String.IsNullOrEmpty(minRuntimeVersion)) { minRuntimeVersion = "2.0.31005.0"; } break; } } } stream.Close(); } else { this.WriteMessage(MessageLevel.Warn, String.Format( "The file '{0}' for the art target '{1}' was not found.", target.InputPath, target.Id)); } string src = null; if (target.FormatXPath == null) { src = target.LinkPath; } else { // WebDocs way, which uses the 'format' xpath expression // to calculate the target path and then makes it // relative to the current page if the 'relative-to' // attribute is used. src = BuildComponentUtilities.EvalXPathExpr(document, target.FormatXPath, "key", Path.GetFileName(outputPath)); if (target.RelativeToXPath != null) { src = BuildComponentUtilities.GetRelativePath(src, BuildComponentUtilities.EvalXPathExpr(document, target.RelativeToXPath, "key", key)); } } _silverlightInsertScript = true; _silverlightInsertError = true; //<div id="silverlightControlHost"> // <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> // <param name="source" value="ClientBin/SilverlightApplication2.xap"/> // <param name="onError" value="onSilverlightError" /> // <param name="background" value="white" /> // <param name="minRuntimeVersion" value="3.0.40818.0" /> // <param name="autoUpgrade" value="true" /> // <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none"> // <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/> // </a> // </object> //</div> string unit = target.UnitText; int width = target.Width; int height = target.Height; if (width <= 0 || height <= 0) { width = 100; height = 100; unit = "%"; } XmlWriter writer = artLink.InsertAfter(); writer.WriteStartElement("div"); // start - div writer.WriteAttributeString("id", target.Id); writer.WriteStartElement("object"); // start - object writer.WriteAttributeString("data", "data:application/x-silverlight-2,"); writer.WriteAttributeString("type", "application/x-silverlight-2"); writer.WriteAttributeString("width", width.ToString() + unit); writer.WriteAttributeString("height", height.ToString() + unit); writer.WriteStartElement("param"); // start - param writer.WriteAttributeString("name", "source"); writer.WriteAttributeString("value", src); writer.WriteEndElement(); // end - param writer.WriteStartElement("param"); // start - param writer.WriteAttributeString("name", "onError"); writer.WriteAttributeString("value", "onSilverlightError"); writer.WriteEndElement(); // end - param writer.WriteStartElement("param"); // start - param writer.WriteAttributeString("name", "background"); writer.WriteAttributeString("value", "white"); writer.WriteEndElement(); // end - param writer.WriteStartElement("param"); // start - param writer.WriteAttributeString("name", "minRuntimeVersion"); writer.WriteAttributeString("value", minRuntimeVersion); writer.WriteEndElement(); // end - param writer.WriteStartElement("param"); // start - param writer.WriteAttributeString("name", "autoUpgrade"); writer.WriteAttributeString("value", "true"); writer.WriteEndElement(); // end - param writer.WriteStartElement("a"); // start - a writer.WriteAttributeString("href", "http://go.microsoft.com/fwlink/?LinkID=149156"); writer.WriteAttributeString("style", "text-decoration:none"); writer.WriteStartElement("img"); // start - img writer.WriteAttributeString("src", "http://go.microsoft.com/fwlink/?LinkId=161376"); writer.WriteAttributeString("alt", "Get Microsoft Silverlight"); writer.WriteAttributeString("style", "border-style:none"); writer.WriteEndElement(); // end - img writer.WriteEndElement(); // end - a writer.WriteEndElement(); // end - object writer.WriteEndElement(); // end - div writer.Close(); artLink.DeleteSelf(); }
public override void Apply(XmlDocument document, string key) { if (_flashTargets != null) { _flashTargets.Clear(); } _silverlightInsertScript = false; _silverlightInsertError = false; XPathNavigator documentNavigator = document.CreateNavigator(); // The transformation converts the <mediaLink/> tags to the format: // <artLink target="2aca5da4-6f94-43a0-9817-5f413d16f801" /> XPathNodeIterator artLinkIterator = documentNavigator.Select(_artLinkExpression); if (artLinkIterator == null || artLinkIterator.Count == 0) { return; } XPathNavigator[] artLinks = BuildComponentUtilities.ConvertNodeIteratorToArray(artLinkIterator); foreach (XPathNavigator artLink in artLinks) { string name = artLink.GetAttribute("target", String.Empty); MediaTarget target = this[name]; if (target != null) { switch (target.Media) { case MediaType.None: case MediaType.Image: InsertImage(document, key, artLink, target); break; case MediaType.Flash: InsertFlash(document, key, artLink, target); break; case MediaType.Silverlight: InsertSilverlight(document, key, artLink, target); break; case MediaType.Pdf: InsertPdf(document, key, artLink, target); break; case MediaType.Xps: InsertXps(document, key, artLink, target); break; case MediaType.Video: break; case MediaType.YouTube: InsertYouTube(document, key, artLink, target); break; default: InsertImage(document, key, artLink, target); break; } } else { this.WriteMessage(MessageLevel.Warn, String.Format( "Unknown art target '{0}'", name)); } } if (_flashTargets != null && _flashTargets.Count != 0) { this.ApplyFlash(document, key, documentNavigator); } if (_silverlightInsertScript || _silverlightInsertError) { this.ApplySilverlight(document, key, documentNavigator); } }
public override void Apply(XmlDocument document, string key) { XPathNodeIterator artLinkIterator = document.CreateNavigator().Select(_artLinkExpression); if (artLinkIterator == null || artLinkIterator.Count == 0) { return; } XPathNavigator[] artLinks = BuildComponentUtilities.ConvertNodeIteratorToArray(artLinkIterator); string tempText = null; foreach (XPathNavigator artLink in artLinks) { string name = artLink.GetAttribute("href", String.Empty); string placement = artLink.GetAttribute("placement", String.Empty); if (String.IsNullOrEmpty(name)) { // If the href attribute is not there, we look for the image tag XPathNavigator imageNode = artLink.SelectSingleNode("image"); if (imageNode != null) { name = imageNode.GetAttribute("href", String.Empty); tempText = imageNode.GetAttribute("placement", String.Empty); if (!String.IsNullOrEmpty(tempText)) { placement = tempText; } } if (String.IsNullOrEmpty(name)) { // If the href is still not found, warn and move on // with other nodes... this.WriteMessage(MessageLevel.Warn, String.Format( "A media link '{0}' for '{1}' is not valid, the href attribute is missing.", artLink.LocalName, key)); continue; } } MediaTarget target = this[name]; if (target != null) { // evaluate the path string path = document.CreateNavigator().Evaluate( target.OutputXPath).ToString(); if (target.baseOutputPath != null) { path = Path.Combine(target.baseOutputPath, path); } string outputPath = Path.Combine(path, target.Name); string targetDirectory = Path.GetDirectoryName(outputPath); if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } if (File.Exists(target.InputPath)) { if (File.Exists(outputPath)) { File.SetAttributes(outputPath, FileAttributes.Normal); } File.Copy(target.InputPath, outputPath, true); } else { this.WriteMessage(MessageLevel.Warn, String.Format( "The file '{0}' for the art target '{1}' in '{2}' was not found.", target.InputPath, name, key)); } XmlWriter writer = artLink.InsertAfter(); if (String.Equals(artLink.LocalName, "mediaLink", StringComparison.OrdinalIgnoreCase)) { XPathNavigator captionNode = artLink.SelectSingleNode("caption"); string captionText = null; string captionLead = null; bool captionAfter = false; if (captionNode != null) { tempText = captionNode.GetAttribute("location", String.Empty); if (String.IsNullOrEmpty(tempText)) { tempText = captionNode.GetAttribute("placement", String.Empty); } if (!String.IsNullOrEmpty(tempText) && (tempText.Equals("after", StringComparison.OrdinalIgnoreCase) || tempText.Equals("bottom", StringComparison.OrdinalIgnoreCase))) { captionAfter = true; } captionLead = captionNode.GetAttribute("lead", String.Empty); captionText = captionNode.Value; } if (String.IsNullOrEmpty(placement)) { placement = "mediaLeft"; } else { if (placement.Equals("near", StringComparison.OrdinalIgnoreCase) || placement.Equals("left", StringComparison.OrdinalIgnoreCase)) { placement = "mediaLeft"; } else if (placement.Equals("far", StringComparison.OrdinalIgnoreCase) || placement.Equals("right", StringComparison.OrdinalIgnoreCase)) { placement = "mediaRight"; } else if (placement.Equals("center", StringComparison.OrdinalIgnoreCase) || placement.Equals("centre", StringComparison.OrdinalIgnoreCase) || placement.Equals("middle", StringComparison.OrdinalIgnoreCase)) { placement = "mediaMiddle"; } else { placement = "mediaLeft"; } } writer.WriteStartElement("div"); // start: div writer.WriteAttributeString("class", placement); if (!String.IsNullOrEmpty(captionText) && !captionAfter) { this.WriteTitle(writer, captionText, captionLead); } // Now, write the image... this.WriteImage(document, key, outputPath, writer, target); if (!String.IsNullOrEmpty(captionText) && captionAfter) { this.WriteTitle(writer, captionText, captionLead); } writer.WriteEndElement(); // end: div } else // For the inline media... { this.WriteImage(document, key, outputPath, writer, target); } writer.Close(); artLink.DeleteSelf(); } else { this.WriteMessage(MessageLevel.Warn, String.Format( "Unknown art target '{0}' in '{1}'", name, key)); } } }
private void InsertXps(XmlDocument document, string key, XPathNavigator artLink, MediaTarget target) { // evaluate the path string path = document.CreateNavigator().Evaluate( target.OutputXPath).ToString(); if (target.baseOutputPath != null) { path = Path.Combine(target.baseOutputPath, path); } string outputPath = Path.Combine(path, target.Name); string targetDirectory = Path.GetDirectoryName(outputPath); if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } if (File.Exists(target.InputPath)) { if (File.Exists(outputPath)) { File.SetAttributes(outputPath, FileAttributes.Normal); } File.Copy(target.InputPath, outputPath, true); } else { this.WriteMessage(MessageLevel.Warn, String.Format( "The file '{0}' for the media target '{1}' was not found.", target.InputPath, target.Id)); } XmlWriter writer = artLink.InsertAfter(); writer.WriteStartElement("iframe"); string data = String.Empty; if (target.FormatXPath == null) { data = target.LinkPath; } else { // WebDocs way, which uses the 'format' xpath expression // to calculate the target path and then makes it // relative to the current page if the 'relative-to' // attribute is used. data = BuildComponentUtilities.EvalXPathExpr(document, target.FormatXPath, "key", Path.GetFileName(outputPath)); if (target.RelativeToXPath != null) { data = BuildComponentUtilities.GetRelativePath(data, BuildComponentUtilities.EvalXPathExpr(document, target.RelativeToXPath, "data", key)); } } writer.WriteAttributeString("src", data); writer.WriteAttributeString("type", "application/vnd.ms-xpsdocument"); string unit = target.UnitText; int width = target.Width; int height = target.Height; if (width <= 0 || height <= 0) { width = 100; height = 100; unit = "%"; } writer.WriteAttributeString("width", width.ToString() + unit); writer.WriteAttributeString("height", height.ToString() + unit); writer.WriteStartElement("p"); // start - p writer.WriteStartElement("a"); // start - a writer.WriteAttributeString("href", data); if (!String.IsNullOrEmpty(target.Text)) { writer.WriteString(target.Text); } writer.WriteEndElement(); // end - a writer.WriteEndElement(); // end - p writer.WriteEndElement(); writer.Close(); artLink.DeleteSelf(); }
//===================================================================== /// <summary> /// This is implemented to resolve the conceptual links /// </summary> /// <param name="document">The XML document with which to work.</param> /// <param name="key">The key (member name) of the item being /// documented.</param> public override void Apply(XmlDocument document, string key) { ConceptualLinkInfo info; TargetInfo targetInfo; LinkType linkType; string url, text; foreach (XPathNavigator navigator in BuildComponentUtilities.ConvertNodeIteratorToArray( document.CreateNavigator().Select(conceptualLinks))) { info = ConceptualLinkInfo.Create(navigator); url = text = null; linkType = LinkType.None; if (validGuid.IsMatch(info.Target)) { targetInfo = this.GetTargetInfoFromCache(info.Target.ToLower(CultureInfo.InvariantCulture)); if (targetInfo == null) { // EFW - Removed linkType = Index, broken links should use the None style. text = this.BrokenLinkDisplayText(info.Target, info.Text); base.WriteMessage(MessageLevel.Warn, String.Format(CultureInfo.InvariantCulture, "Unknown conceptual link target '{0}'.", info.Target)); } else { url = targetInfo.Url; // EFW - Append the anchor if one was specified if (!String.IsNullOrEmpty(info.Anchor)) { url += info.Anchor; } // EFW - Use the link text if specified if (!String.IsNullOrEmpty(info.Text)) { text = info.Text; } else { text = targetInfo.Text; } linkType = targetInfo.LinkType; } } else { // EFW - Removed linkType = Index, broken links should use the None style. text = this.BrokenLinkDisplayText(info.Target, info.Text); base.WriteMessage(MessageLevel.Warn, String.Format(CultureInfo.InvariantCulture, "Invalid conceptual link target '{0}'.", info.Target)); } XmlWriter writer = navigator.InsertAfter(); switch (linkType) { case LinkType.None: writer.WriteStartElement("span"); writer.WriteAttributeString("class", "nolink"); break; case LinkType.Local: writer.WriteStartElement("a"); writer.WriteAttributeString("href", url); WriteHtmlAttributes(writer, info); break; case LinkType.Index: writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp"); writer.WriteAttributeString("keywords", info.Target.ToLower(CultureInfo.InvariantCulture)); writer.WriteAttributeString("tabindex", "0"); break; case LinkType.Id: writer.WriteStartElement("a"); writer.WriteAttributeString("href", String.Format(CultureInfo.InvariantCulture, "ms-xhelp://?Id={0}", info.Target)); break; } writer.WriteString(text); writer.WriteEndElement(); writer.Close(); navigator.DeleteSelf(); } }
private void ApplyTokens(XPathNavigator documentNavigator, string key) { XPathNodeIterator iterator = documentNavigator.Select(_tokensSelector); if (iterator == null || iterator.Count == 0) { return; } XPathNavigator[] navigators = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); int itemCount = navigators.Length; for (int i = 0; i < itemCount; i++) { XPathNavigator navigator = navigators[i]; string nodeText = navigator.Value; if (nodeText != null) { nodeText = nodeText.Trim(); } if (!String.IsNullOrEmpty(nodeText)) { if (_enableAutoOutlines && nodeText.Equals("autoOutline", StringComparison.OrdinalIgnoreCase)) { XmlWriter writer = navigator.InsertAfter(); writer.WriteStartElement("autoOutline", ""); if (_autoOutlineDepth > 0) { writer.WriteString(_autoOutlineDepth.ToString()); } writer.WriteEndElement(); writer.Close(); } else if (_enableLineBreaks && nodeText.Equals("lineBreak", StringComparison.OrdinalIgnoreCase)) { XmlWriter writer = navigator.InsertAfter(); writer.WriteStartElement("span"); writer.WriteAttributeString("name", "SandTokens"); writer.WriteAttributeString("class", "tgtSentence"); writer.WriteString("lineBreak"); writer.WriteEndElement(); writer.Close(); } else if (_enableIconColumns && nodeText.Equals("iconColumn", StringComparison.OrdinalIgnoreCase)) { XmlWriter writer = navigator.InsertAfter(); writer.WriteStartElement("span"); writer.WriteAttributeString("name", "SandTokens"); writer.WriteAttributeString("class", "tgtSentence"); writer.WriteString("iconColumn"); writer.WriteEndElement(); writer.Close(); } } navigator.DeleteSelf(); } }
public override void Apply(XmlDocument document, string key) { // If there is no LaTeX installed, we do no process the math, as this // will throw exceptions... if (!_isLaTeXInstalled) { return; } if (_latexFormatter == null) { return; } if (_numberByPage) { _mathNumber = 1; } try { XPathNavigator docNavigator = document.CreateNavigator(); XPathNodeIterator iterator = docNavigator.Select(_xpathSelector); XPathNavigator navigator = null; XPathNavigator[] arrNavigator = BuildComponentUtilities.ConvertNodeIteratorToArray(iterator); if (arrNavigator == null) { return; } int itemCount = arrNavigator.Length; for (int i = 0; i < itemCount; i++) { navigator = arrNavigator[i]; if (navigator == null) { continue; } string mathInfo = navigator.GetAttribute("address", String.Empty); //if (String.IsNullOrEmpty(mathInfo)) //{ // // default to mimeTex // mathInfo = "MathTeX." + _mathNumber.ToString(); //} string mathText = navigator.Value; if (String.IsNullOrEmpty(mathText)) { continue; } mathText = mathText.Trim(); _isNumbered = true; // We dynamically create the mediaLink element //<mediaLink> // <image xlink:href=""/> //</mediaLink> string mediaFormat = FormatEquation(mathInfo, mathText); if (!String.IsNullOrEmpty(mediaFormat)) { XmlWriter xmlWriter = navigator.InsertAfter(); xmlWriter.WriteStartElement(_isInline ? "mediaLinkInline" : "mediaLink"); // start - mediaLink xmlWriter.WriteStartElement("image"); // start - image xmlWriter.WriteAttributeString("xlink", "href", null, mediaFormat); xmlWriter.WriteEndElement(); // end - image xmlWriter.WriteEndElement(); // end - mediaLink xmlWriter.Close(); if (_isNumbered) { _mathNumber++; } navigator.DeleteSelf(); } else { this.WriteMessage(MessageLevel.Warn, String.Format("Math item not valid - {0}", mathInfo)); //navigator.DeleteSelf(); } } } catch (System.Exception ex) { this.WriteMessage(MessageLevel.Error, ex); } }