diff --git a/OneMore/Commands/References/BiLinkCommand.cs b/OneMore/Commands/References/BiLinkCommand.cs index 528dfee826..c951d71792 100644 --- a/OneMore/Commands/References/BiLinkCommand.cs +++ b/OneMore/Commands/References/BiLinkCommand.cs @@ -263,7 +263,7 @@ private void NormalizeCData(XElement element) */ element.DescendantNodes().OfType().ToList().ForEach(c => { - var doc = new Hap.HtmlDocument() + var doc = new Hap.HtmlDocument { GlobalAttributeValueQuote = Hap.AttributeValueQuote.SingleQuote }; diff --git a/OneMore/Commands/Snippets/InsertTocCommand.cs b/OneMore/Commands/Snippets/InsertTocCommand.cs index f92b6baf3b..c5affb552c 100644 --- a/OneMore/Commands/Snippets/InsertTocCommand.cs +++ b/OneMore/Commands/Snippets/InsertTocCommand.cs @@ -99,7 +99,7 @@ private async Task RefreshToc() var parts = meta.Attribute("content").Value.Split(';'); var options = parts.Select(p => p.Split('=')).ToDictionary(s => s[0], s => s[1]); var addTopLinks = options.ContainsKey("addTopLinks") && options["addTopLinks"] == "True"; - var rightAlignTopLinks= options.ContainsKey("rightAlignTopLinks") && options["rightAlignTopLinks"] == "True"; + var rightAlignTopLinks = options.ContainsKey("rightAlignTopLinks") && options["rightAlignTopLinks"] == "True"; // remove the containing OE so it can be regenerated meta.Parent.Remove(); @@ -167,13 +167,13 @@ private async Task InsertHeadingsTable(Page page, bool addTopLinks, bool rightAl }; // use the minimum intent level - var minlevel = headings.Min(e => e.Style.Index); + var minlevel = headings.Min(e => e.Level); foreach (var heading in headings) { var text = new StringBuilder(); var count = minlevel; - while (count < heading.Style.Index) + while (count < heading.Level) { text.Append("\t"); count++; @@ -189,9 +189,11 @@ private async Task InsertHeadingsTable(Page page, bool addTopLinks, bool rightAl text.Append(heading.Text); } + //text.Append($"(count:{count}=level:{heading.Level})"); + toc.Add(new Paragraph(text.ToString()).SetStyle($"color:{textColor}")); - if (addTopLinks) + if (addTopLinks && !heading.HasTopLink) { if (rightAlignTopLinks) { diff --git a/OneMore/Models/Heading.cs b/OneMore/Models/Heading.cs index 676d18c869..ec87d0a7bd 100644 --- a/OneMore/Models/Heading.cs +++ b/OneMore/Models/Heading.cs @@ -33,6 +33,12 @@ internal class Heading public string Text; + /// + /// True if the header is followed by the [Top of page] link from TOC + /// + public bool HasTopLink; + + /// /// True if the header is an internal OneNote hyperlink to another page; /// used by Split and Merge diff --git a/OneMore/Models/PageHeadings.cs b/OneMore/Models/PageHeadings.cs index a0b95f35a3..13724dac50 100644 --- a/OneMore/Models/PageHeadings.cs +++ b/OneMore/Models/PageHeadings.cs @@ -11,6 +11,8 @@ namespace River.OneMoreAddIn.Models using System.Text.RegularExpressions; using System.Xml; using System.Xml.Linq; + using Hap = HtmlAgilityPack; + using Resx = River.OneMoreAddIn.Properties.Resources; internal partial class Page @@ -41,8 +43,10 @@ public List GetHeadings(OneNote one) var blocks = from e in Root.Elements(Namespace + "Outline").Descendants(Namespace + "OE") + // get the first non-empty CDATA let c = e.Elements(Namespace + "T").DescendantNodes() - .FirstOrDefault(p => p.NodeType == XmlNodeType.CDATA) as XCData + .FirstOrDefault(p => + p.NodeType == XmlNodeType.CDATA && (((XCData)p).Value.Length > 0)) as XCData where c?.Value.Length > 0 && !Regex.IsMatch(c.Value, @"[\s\b]+().FirstOrDefault(); + if (cdata != null) + { + var doc = new Hap.HtmlDocument(); + doc.LoadHtml(cdata.Value); + var text = doc.DocumentNode.InnerText; + + if (text == Resx.InsertTocCommand_Top) + { + heading.HasTopLink = true; + } + } + } + } + + private string GetHyperlink(XElement element, OneNote one) { var attr = element.Attribute("objectID"); @@ -187,25 +234,34 @@ private Style FindCustomStyle(XElement block) /// private void ResetHeadingStyleIndexes() { - quickStyles = quickStyles.Where(s => Regex.IsMatch(s.Name, @"h(\d+)")).ToList(); + // internal names are h1..h6 + quickStyles = quickStyles.Where(s => Regex.IsMatch(s.Name, @"^h\d$")).ToList(); foreach (var style in quickStyles) { - var match = Regex.Match(style.Name, @"h(\d+)"); + var match = Regex.Match(style.Name, @"^h(\d)$"); if (match.Success && match.Captures.Count > 0) { if (int.TryParse(match.Captures[0].Value, out var index)) { - style.Index = index; + style.Index = index - 1; } } } - quickStyles = quickStyles.OrderBy(s => s.Index).ToList(); + quickStyles = quickStyles.OrderBy(s => s.Name).ToList(); - for (int i = 0; i < quickStyles.Count; i++) + string name = null; + for (int i = 0, j = 0; i < quickStyles.Count; i++) { - quickStyles[i].Index = i; + // there are cases where OneNote will duplicate quick styles + if (quickStyles[i].Name != name) + { + name = quickStyles[i].Name; + j++; + } + + quickStyles[i].Index = j; } for (int i = 0; i < customStyles.Count; i++) diff --git a/OneMore/Properties/AssemblyInfo.cs b/OneMore/Properties/AssemblyInfo.cs index cb2fa78874..ed9649f23a 100644 Binary files a/OneMore/Properties/AssemblyInfo.cs and b/OneMore/Properties/AssemblyInfo.cs differ diff --git a/OneMoreProtocolHandler/Properties/AssemblyInfo.cs b/OneMoreProtocolHandler/Properties/AssemblyInfo.cs index a674067ef4..7374541a34 100644 Binary files a/OneMoreProtocolHandler/Properties/AssemblyInfo.cs and b/OneMoreProtocolHandler/Properties/AssemblyInfo.cs differ diff --git a/OneMoreSetup/OneMoreSetup.vdproj b/OneMoreSetup/OneMoreSetup.vdproj index c919049908..fe2104c8e4 100644 Binary files a/OneMoreSetup/OneMoreSetup.vdproj and b/OneMoreSetup/OneMoreSetup.vdproj differ