public override void Apply(XmlDocument document, string key)
        {
            // Run through all conceptual nodes, make sure the target is a valid GUID, attempt to resolve the target
            // to a link using one of the TargetSet definitions, and then replace the node with the result. Errors
            // will be dealt with as follows: 1) bad target (GUID) -> output invalidLinkFormat; 2) broken link (cannot
            // resolve target or the URL is empty) -> output brokenLinkFormat; 3) missing text -> just delete the node
            // and don't output anything (presumably there's no point in creating a link that nobody can see). In all
            // three cases we'll log the problem as a warning.
            string docBaseUrl = baseUrl == null ? null : BuildComponentUtilities.EvalXPathExpr(document, baseUrl, "key", key);

            XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(document.CreateNavigator().Select(conceptualLinks));
            foreach (XPathNavigator node in linkNodes)
            {
                string targetGuid = node.GetAttribute("target", String.Empty);
                string url        = targetGuid;
                string text       = node.ToString();
                string format;
                if (validGuid.IsMatch(url))
                {
                    format = brokenLinkFormat;
                    Target t = targetSets.Lookup(targetGuid);
                    if (t == null)
                    {
                        WriteMessage(MessageLevel.Warn, String.Format("Conceptual link not found in target sets; target={0}", targetGuid));
                    }
                    else
                    {
                        if (!String.IsNullOrEmpty(t.Url))
                        {
                            format = t.TargetSet.Format;
                            url    = (docBaseUrl != null && t.TargetSet.RelativeUrl) ?
                                     BuildComponentUtilities.GetRelativePath(t.Url, docBaseUrl) : t.Url;
                            if (!String.IsNullOrEmpty(t.Text))
                            {
                                text = t.Text;
                            }
                        }
                        else
                        {
                            WriteMessage(MessageLevel.Warn, String.Format("Conceptual link found in target set, but meta data does not specify a url; target={0}", targetGuid));
                        }
                    }
                }
                else
                {
                    format = invalidLinkFormat;
                }

                if (String.IsNullOrEmpty(text))
                {
                    node.DeleteSelf();
                    WriteMessage(MessageLevel.Warn, String.Format("Skipping conceptual link without text; target={0}", url));
                }
                else
                {
                    node.OuterXml = String.Format(format, url, text);
                }
            }
        }
Ejemplo n.º 2
0
        // component logic

        public override void Apply(XmlDocument document, string key)
        {
            // XmlNodeList link_nodes = document.SelectNodes("//referenceLink");
            XPathNodeIterator linkIterator = document.CreateNavigator().Select(referenceLinkExpression);

            XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator);

            foreach (XPathNavigator linkNode in linkNodes)
            {
                // extract link information
                ReferenceLinkInfo2 link = ReferenceLinkInfo2.Create(linkNode);

                if (link == null)
                {
                    WriteMessage(MessageLevel.Warn, "Invalid referenceLink element.");
                }
                else
                {
                    // determine target, link type, and display options
                    string         targetId = link.Target;
                    DisplayOptions options  = link.DisplayOptions;
                    LinkType2      type     = LinkType2.None;

                    Target target = GetTarget(targetId);
                    if (target == null)
                    {
                        // no such target known; set link type to none and warn
                        type = LinkType2.None;
                        WriteMessage(MessageLevel.Warn, String.Format("Unknown reference link target '{0}'.", targetId));
                    }
                    else
                    {
                        // if overload is prefered and found, change targetId and make link options hide parameters
                        if (link.PreferOverload)
                        {
                            bool isConversionOperator = false;

                            MethodTarget method = target as MethodTarget;
                            if (method != null)
                            {
                                isConversionOperator = method.conversionOperator;
                            }

                            MemberTarget member = target as MemberTarget;

                            // 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 | DisplayOptions.ShowParameters;
                            }
                            else
                            {
                                options = options & ~DisplayOptions.ShowParameters;
                            }
                        }

                        // get stored link type
                        type = target.DefaultLinkType;

                        // if link type is local or index, determine which
                        if (type == LinkType2.LocalOrIndex)
                        {
                            if ((key != null) && targets.Contains(key) && (target.Container == targets[key].Container))
                            {
                                type = LinkType2.Local;
                            }
                            else
                            {
                                type = LinkType2.Index;
                            }
                        }
                    }

                    // links to this page are not live
                    if (targetId == key)
                    {
                        type = LinkType2.Self;
                    }
                    else if ((target != null) && (key != null) && targets.Contains(key) && (target.File == targets[key].File))
                    {
                        type = LinkType2.Self;
                    }

                    // get msdn or external endpoint, if needed
                    string externalUrl = null;
                    if (type == LinkType2.Msdn || type == LinkType2.External)
                    {
                        externalUrl = ResolveExternalUrl(targetId, type);
                        if (String.IsNullOrEmpty(externalUrl))
                        {
                            type = LinkType2.None;
                        }
                    }

                    // write opening link tag and target info
                    XmlWriter writer = linkNode.InsertAfter();
                    switch (type)
                    {
                    case LinkType2.None:
                        writer.WriteStartElement("span");
                        writer.WriteAttributeString("class", "nolink");
                        break;

                    case LinkType2.Self:
                        writer.WriteStartElement("span");
                        writer.WriteAttributeString("class", "selflink");
                        break;

                    case LinkType2.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 LinkType2.Index:
                        writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp");
                        writer.WriteAttributeString("keywords", targetId);
                        writer.WriteAttributeString("tabindex", "0");
                        break;

                    case LinkType2.Msdn:
                    case LinkType2.External:
                        writer.WriteStartElement("a");
                        writer.WriteAttributeString("href", externalUrl);
                        writer.WriteAttributeString("target", linkTarget);
                        break;
                    }

                    // write the link text
                    if (String.IsNullOrEmpty(link.DisplayTarget))
                    {
                        if (link.Contents == null)
                        {
                            if (target != null)
                            {
                                resolver.WriteTarget(target, options, writer);
                            }
                            else
                            {
                                //Console.WriteLine("Attemting to create reference");
                                Reference reference = TextReferenceUtilities.CreateReference(targetId);
                                //Console.WriteLine("Returned");
                                if (reference is InvalidReference)
                                {
                                    WriteMessage(MessageLevel.Warn, String.Format("Invalid reference link target '{0}'.", targetId));
                                }
                                resolver.WriteReference(reference, options, writer);
                            }
                        }
                        else
                        {
                            // write contents to writer
                            link.Contents.WriteSubtree(writer);
                        }
                    }
                    else
                    {
                        //Console.WriteLine("Display target = {0}", link.DisplayTarget);
                        if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null))
                        {
                            // Use the contents as an XML representation of the display target

                            //Console.WriteLine(link.Contents.NodeType);
                            Reference reference = XmlTargetCollectionUtilities.CreateReference(link.Contents);
                            //Console.WriteLine(reference.GetType().FullName);
                            resolver.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;
                            //Console.WriteLine("format = {0}", format);

                            string       input     = null;
                            StringWriter textStore = new StringWriter();
                            try {
                                XmlWriterSettings settings = new XmlWriterSettings();
                                settings.ConformanceLevel = ConformanceLevel.Fragment;

                                XmlWriter xmlStore = XmlWriter.Create(textStore, settings);
                                try {
                                    if (target != null)
                                    {
                                        resolver.WriteTarget(target, options, xmlStore);
                                    }
                                    else
                                    {
                                        Reference reference = TextReferenceUtilities.CreateReference(targetId);
                                        resolver.WriteReference(reference, options, xmlStore);
                                    }
                                } finally {
                                    xmlStore.Close();
                                }
                                input = textStore.ToString();
                            } finally {
                                textStore.Close();
                            }
                            //Console.WriteLine("input = {0}", input);

                            string output = String.Format(format, input);
                            //Console.WriteLine("output = {0}", output);

                            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 = XmlTargetCollectionUtilities.CreateExtensionMethodReference(link.Contents);
                            resolver.WriteReference(extMethodReference, options, writer);
                        }
                        else
                        {
                            // Use the display target value as a CER for the display target

                            TextReferenceUtilities.SetGenericContext(key);
                            Reference reference = TextReferenceUtilities.CreateReference(link.DisplayTarget);
                            //Console.WriteLine("Reference is {0}", reference.GetType().FullName);
                            resolver.WriteReference(reference, options, writer);
                        }
                    }

                    // write the closing link tag
                    writer.WriteEndElement();
                    writer.Close();
                }

                // delete the original tag
                linkNode.DeleteSelf();
            }
        }
Ejemplo n.º 3
0
        public override void Apply(XmlDocument document, string id)
        {
            XPathNodeIterator artLinkIterator = document.CreateNavigator().Select(artLinkExpression);

            XPathNavigator[] artLinks = BuildComponentUtilities.ConvertNodeIteratorToArray(artLinkIterator);
            foreach (XPathNavigator artLink in artLinks)
            {
                string name = artLink.GetAttribute("target", String.Empty).ToLower();

                if (targets.ContainsKey(name))
                {
                    ArtTarget target = targets[name];

                    // 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
                    {
                        WriteMessage(MessageLevel.Warn, String.Format("The file '{0}' for the art target '{1}' was not found.", target.InputPath, name));
                    }

                    // Get the relative art path for HXF generation.
                    int    index   = target.LinkPath.IndexOf('/');
                    string artPath = target.LinkPath.Substring(index + 1, target.LinkPath.Length - (index + 1));

                    FileCreatedEventArgs fe = new FileCreatedEventArgs(artPath, Path.GetDirectoryName(path));
                    OnComponentEvent(fe);

                    XmlWriter writer = artLink.InsertAfter();

                    writer.WriteStartElement("img");
                    if (!String.IsNullOrEmpty(target.Text))
                    {
                        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", id));
                        }
                        writer.WriteAttributeString("src", src);
                    }

                    writer.WriteEndElement();

                    writer.Close();

                    artLink.DeleteSelf();
                }
                else
                {
                    WriteMessage(MessageLevel.Warn, String.Format("Unknown art target '{0}'", name));
                }
            }
        }