/// <summary> /// This is used to add the related topic links /// </summary> /// <param name="converter">The converter used to add the elements</param> /// <param name="s">The section used to contain the links</param> /// <param name="links">The list of links to add</param> /// <param name="sectionTitle">The section title</param> private static void AddRelatedTopicLinks(MamlToFlowDocumentConverter converter, Section s, List<XElement> links, string sectionTitle) { Paragraph p; bool isFirst = true; if(links.Count != 0) { p = new Paragraph(new Run(sectionTitle)); s.Blocks.Add(p); p.SetResourceReference(Paragraph.StyleProperty, NamedStyle.RelatedTopicTitle); p = new Paragraph(); s.Blocks.Add(p); p.SetResourceReference(Paragraph.StyleProperty, NamedStyle.NoTopMargin); foreach(var link in links) { if(isFirst) isFirst = false; else p.Inlines.Add(new LineBreak()); converter.ParseChildren(p, new[] { link }); } } }
/// <summary> /// This is used to render a glossary division /// </summary> /// <param name="d">The root glossary division element</param> /// <param name="divisionId">The division ID used as a prefix for each letter section in the division</param> /// <param name="entries">An enumerable list of all glossary entries</param> /// <param name="converter">The converter to which the glossary elements will be added</param> /// <returns>An enumerable list of blocks that define the glossary division in the document</returns> private static void RenderGlossaryDivision(XElement d, string divisionId, IEnumerable<GlossaryEntry> entries, MamlToFlowDocumentConverter converter) { Section s; Paragraph p = new Paragraph(); bool isFirst = true; // Group all entries in this division by the first letter of the first term var groupLetters = entries.Where(g => g.Parent == d).GroupBy( g => Char.ToUpperInvariant(g.Terms.First().Key[0])).OrderBy(g => g.Key); // Generate the letter bar for the division for(char ch = 'A'; ch <= 'Z'; ch++) { if(isFirst) isFirst = false; else p.Inlines.Add(new Run(" | ")); if(!groupLetters.Any(g => g.Key == ch)) p.Inlines.Add(new Bold(new Run(ch.ToString()))); else p.Inlines.Add(new Hyperlink(new Run(ch.ToString())) { NavigateUri = new Uri("link://#" + divisionId + "_" + ch.ToString()) }); } converter.AddNonParentToBlockContainer(p); p.SetResourceReference(Paragraph.StyleProperty, NamedStyle.GlossaryLetterBar); foreach(var g in groupLetters) { p = new Paragraph(new Run(g.Key.ToString()) { Name = ToElementName(divisionId + "_" + g.Key.ToString()) }); converter.AddNonParentToBlockContainer(p); p.SetResourceReference(Paragraph.StyleProperty, NamedStyle.GlossaryLetterTitle); foreach(var entry in g) { s = new Section(); converter.AddNonParentToBlockContainer(s); s.SetResourceReference(Section.StyleProperty, NamedStyle.GlossaryDefinition); p = new Paragraph(); isFirst = true; foreach(var t in entry.Terms) { if(isFirst) isFirst = false; else p.Inlines.Add(new Run(", ")); p.Inlines.Add(new Bold(new Run(t.Key)) { Name = (t.Value == null) ? String.Empty : ToElementName(t.Value) }); } s.Blocks.Add(p); p.SetResourceReference(Paragraph.StyleProperty, NamedStyle.NoMargin); converter.ParseChildren(s, entry.Definition.Nodes()); if(entry.RelatedEntries.Count != 0) { p = new Paragraph(); p.Inlines.Add(new Run("See also: ")); isFirst = true; foreach(var r in entry.RelatedEntries) { if(isFirst) isFirst = false; else p.Inlines.Add(new Run(", ")); var related = entries.SelectMany(e => e.Terms).FirstOrDefault(t => t.Value == r); if(related.Key != null) p.Inlines.Add(new Hyperlink(new Run(related.Key)) { NavigateUri = new Uri("link://#" + r) }); } p.Inlines.Add(new LineBreak()); s.Blocks.Add(p); } } } }