Example #1
0
        /// <summary>
        /// Create a companion file for a topic
        /// </summary>
        /// <param name="filename">The companion filename.</param>
        /// <param name="topic">The topic</param>
        public static void CreateCompanionFile(string filename, Topic topic)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            XmlWriter writer = null;

            try
            {
                settings.Indent = true;
                settings.CloseOutput = true;
                writer = XmlWriter.Create(filename, settings);

                writer.WriteStartDocument();
                writer.WriteStartElement("metadata");
                writer.WriteAttributeString("fileAssetGuid", topic.Id.ToString());
                writer.WriteAttributeString("assetTypeId", "CompanionFile");

                writer.WriteStartElement("topic");
                writer.WriteAttributeString("id", topic.Id.ToString());

                writer.WriteStartElement("title");
                if(!String.IsNullOrEmpty(topic.Title))
                    writer.WriteValue(topic.Title);
                else
                    writer.WriteValue(Path.GetFileNameWithoutExtension(filename));

                writer.WriteEndElement();   // </title>

                writer.WriteStartElement("tableOfContentsTitle");
                if(!String.IsNullOrEmpty(topic.Title))
                    writer.WriteValue(topic.Title);
                else
                    writer.WriteValue(Path.GetFileNameWithoutExtension(filename));

                writer.WriteEndElement();   // </tableOfContentsTitle>

                foreach(MSHelpAttr attr in topic.HelpAttributes)
                {
                    writer.WriteStartElement("attribute");
                    writer.WriteAttributeString("name", attr.AttributeName);
                    writer.WriteValue(attr.AttributeValue);
                    writer.WriteEndElement();
                }

                foreach(MSHelpKeyword kw in topic.HelpKeywords)
                {
                    writer.WriteStartElement("keyword");
                    writer.WriteAttributeString("index", kw.Index);
                    writer.WriteValue(kw.Term);
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();   // </topic>

                writer.WriteEndElement();   // </metadata>
                writer.WriteEndDocument();
            }
            finally
            {
                if(writer != null)
                    writer.Close();
            }
        }
Example #2
0
        /// <summary>
        /// This is called to convert a single topic and its children
        /// </summary>
        /// <param name="topic">The topic to convert</param>
        public void ConvertTopic(Topic topic)
        {
            StringBuilder sb = new StringBuilder();
            List<string> extras = new List<string>();
            string destFile, tagName, body = topic.Body;
            Regex reRemoveExtra;

            if(topic.SourceFile != null)
            {
                // Save the topic to the destination folder
                destFile = Path.Combine(destPath, topic.SourceFile.Path.Substring(
                    sourcePath.Length + 1));
                destFile = Path.ChangeExtension(destFile, ".aml");

                if(!Directory.Exists(Path.GetDirectoryName(destFile)))
                    Directory.CreateDirectory(Path.GetDirectoryName(destFile));

                this.ReportProgress("{0} -> {1}", topic.SourceFile, destFile);
                currentTopic = topic;

                if(!String.IsNullOrEmpty(body))
                {
                    markupSections.Clear();
                    sectionCount = 0;

                    foreach(Match m in reAllTags.Matches(body))
                    {
                        tagName = m.Groups["Tag"].Value.ToLower(
                            CultureInfo.InvariantCulture);

                        if(!conversionRules.ContainsKey(tagName) &&
                          extras.IndexOf(tagName) == -1)
                        {
                            if(sb.Length != 0)
                                sb.Append("|");

                            sb.Append(tagName);
                            extras.Add(tagName);

                            this.ReportProgress("    Warning: Found unknown tag " +
                                "'{0}' which will be removed", tagName);
                        }
                    }

                    // Replace unrecognized entities
                    body = reReplaceEntity.Replace(body, matchEntity);

                    // Replace markup wrappers with a placeholder
                    body = reMarkupWrapper.Replace(body, matchMarkupWrapper);

                    // Remove tags with no MAML equivalent
                    body = reRemoveTag.Replace(body, String.Empty);

                    if(sb.Length != 0)
                    {
                        sb.Insert(0, @"<\s*/?\s*(");
                        sb.Append(@")\s*?((\s|/)[^>]*?)?>");
                        reRemoveExtra = new Regex(sb.ToString(),
                            RegexOptions.IgnoreCase | RegexOptions.Singleline);

                        body = reRemoveExtra.Replace(body, String.Empty);
                    }

                    // Replace tokens
                    body = reReplaceTokens.Replace(body, matchToken);

                    // Replace tags with their MAML equivalent
                    body = reReplaceTag.Replace(body, matchReplace);

                    // Update <code> tags with the appropriate MAML tag
                    body = reReplaceCode.Replace(body, matchCode);

                    // Replace <see> tags with <codeEntityReference> tags
                    body = reReplaceSee.Replace(body, matchSee);

                    // Replace <a> tags with an appropriate MAML link
                    body = reReplaceAnchor.Replace(body, matchAnchor);

                    // Replace <img> tags with an appropriate MAML media link
                    body = reReplaceImage.Replace(body, matchImage);

                    // Wrap heading tags (h1-h6) in sections
                    isFirstHeading = true;
                    body = reReplaceHeading.Replace(body, matchHeading);

                    if(!isFirstHeading)
                        body += "\r\n  </content>\r\n</section>\r\n";

                    // If wanted, move the leading text before the first section tag into an introduction
                    // element.  This doesn't always produce good results across all topics depending on how
                    // they are formatted so it is optional.
                    if(replaceIntro)
                        body = reReplaceIntroduction.Replace(body, matchIntroduction);

                    // Put the markup wrappers back in the body
                    body = reReplaceMarker.Replace(body, matchMarker);

                    topic.Body = body;

                    // The converted HTML may not be valid XML so we'll write it
                    // out as text rather than using an XML document object.
                    using(StreamWriter sw = new StreamWriter(destFile, false,
                      Encoding.UTF8))
                    {
                        sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                        sw.WriteLine("<topic id=\"{0}\" revisionNumber=\"{1}\">",
                            topic.Id, topic.RevisionNumber);  //DR[12-07-27]:

                        sw.WriteLine("  <developerConceptualDocument\r\n" +
                            "    xmlns=\"http://ddue.schemas.microsoft.com/authoring/2003/5\"\r\n" +
                            "    xmlns:xlink=\"http://www.w3.org/1999/xlink\">\r\n");

                        // If it had an abstract, write that out
                        if(!String.IsNullOrEmpty(topic.TopicAbstract))
                            sw.WriteLine("    <summary abstract=\"true\">\r\n" +
                                topic.TopicAbstract + "\r\n    </summary>");

                        // Insert a default introduction if leading text was not moved above
                        if(!replaceIntro)
                            sw.WriteLine("    <introduction>\r\n      <para>TODO: " +
                                "Move introduction text here</para>\r\n    " +
                                "</introduction>");

                        sw.WriteLine(topic.Body);
                        sw.WriteLine("    <relatedTopics>\r\n    </relatedTopics>\r\n");
                        sw.WriteLine("  </developerConceptualDocument>\r\n</topic>");
                    }

                    if(createCompanionFile)
                        CreateCompanionFile(Path.ChangeExtension(destFile,
                            ".cmp"), topic);
                }
            }

            foreach(Topic t in topic.Subtopics)
                this.ConvertTopic(t);
        }