From c6fc16d0d24f33b623480b17eafb32f40a7bd10e Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Tue, 26 Nov 2024 07:59:15 +0100 Subject: [PATCH 01/13] added todo handling for tables added todo handling for tables --- OneMore/Commands/Edit/ConvertMarkdownCommand.cs | 2 ++ OneMore/Commands/File/ImportCommand.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs index 6c481de5c3..65d71436fb 100644 --- a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs +++ b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs @@ -68,6 +68,8 @@ public override async Task Execute(params object[] args) var text = reader.ReadTextFrom(paragraphs, allContent); text = Regex.Replace(text, @"
([\n\r]+)", "$1"); + text = Regex.Replace(text, @"\<*input\s+type*=*\""checkbox\""\s+unchecked\s+[a-zA-Z *]*\/\>", "[ ]"); + text = Regex.Replace(text, @"\<*input\s+type*=*\""checkbox\""\s+checked\s+[a-zA-Z *]*\/\>", "[x]"); var body = OneMoreDig.ConvertMarkdownToHtml(filepath, text); diff --git a/OneMore/Commands/File/ImportCommand.cs b/OneMore/Commands/File/ImportCommand.cs index 600e9ae4fa..0a0025354a 100644 --- a/OneMore/Commands/File/ImportCommand.cs +++ b/OneMore/Commands/File/ImportCommand.cs @@ -578,6 +578,8 @@ private async Task ImportMarkdownFile(string filepath, CancellationToken token) page.Title = Path.GetFileNameWithoutExtension(filepath); var container = page.EnsureContentContainer(); + body = Regex.Replace(body, @"\<*input\s+type*=*\""checkbox\""\s+unchecked\s+[a-zA-Z *]*\/\>", "[ ]"); + body = Regex.Replace(body, @"\<*input\s+type*=*\""checkbox\""\s+checked\s+[a-zA-Z *]*\/\>", "[x]"); container.Add(new XElement(ns + "HTMLBlock", new XElement(ns + "Data", From 8a34fceb048422af6c752fd170ed3901feb8d535 Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Tue, 26 Nov 2024 08:04:52 +0100 Subject: [PATCH 02/13] Added TAG handling and moved Tag decoding to central place --- .../File/Markdown/MarkdownConverter.cs | 54 ++++++++++--- .../Commands/File/Markdown/MarkdownWriter.cs | 31 +++----- OneMore/Commands/Reminders/RemindCommand.cs | 50 ++----------- OneMore/Models/Page.cs | 75 +++++++++++++++++++ 4 files changed, 136 insertions(+), 74 deletions(-) diff --git a/OneMore/Commands/File/Markdown/MarkdownConverter.cs b/OneMore/Commands/File/Markdown/MarkdownConverter.cs index 3b5fc2bf1f..607f8954c6 100644 --- a/OneMore/Commands/File/Markdown/MarkdownConverter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownConverter.cs @@ -141,8 +141,22 @@ public MarkdownConverter RewriteHeadings(IEnumerable paragraphs) } + /// + /// Applies standard OneNote styling to all recognizable headings in all Outlines + /// on the page + /// + public void RewriteTodo() + { + foreach (var outline in page.BodyOutlines) + { + RewriteTodo(outline.Descendants(ns + "OE")); + } + } + + /// /// Tag current line with To Do tag if beginning with [ ] or [x] + /// Also :TAGS: will be handled here /// All other :emojis: should be translated inline by Markdig /// /// @@ -158,21 +172,43 @@ public MarkdownConverter RewriteTodo(IEnumerable paragraphs) { var cdata = run.GetCData(); var wrapper = cdata.GetWrapper(); + if (wrapper.FirstNode is XText) + { + cdata.Value = wrapper.GetInnerXml(); + } + while (wrapper.FirstNode is not XText && wrapper.FirstNode is not null) + { + wrapper = (XElement)wrapper.FirstNode; + } if (wrapper.FirstNode is XText text) { var match = boxpattern.Match(text.Value); + // special treatment of todo tag if (match.Success) { - text.Value = text.Value.Substring(match.Length); - - // ensure TagDef exists - var index = page.AddTagDef("3", "To Do", 4); - - // inject tag prior to run - run.AddBeforeSelf(new Tag(index, match.Groups["x"].Value == "x")); + var org = text.Value; + var completed = match.Groups["x"].Value == "x"; + text.Value = text.Value.Replace((completed ? "[x]" : "[ ]"), ""); + cdata.Value = cdata.Value.Replace(org, text.Value); + page.SetTag(paragraph, tagSymbol: "3", tagStatus:completed,tagName:"todo"); + } + else + { + // look for all other tags + foreach (var t in page.taglist) + { + // check for other tags + if (text.Value.Contains(t.name)) + { + var org = text.Value; + text.Value = text.Value.Replace(t.name, ""); + cdata.Value = cdata.Value.Replace(org, text.Value); + // ensure TagDef exists + page.SetTag(paragraph, tagSymbol: t.id, tagStatus: false, tagName: t.topic, tagType: t.type); + break; + } + } - // update run text - cdata.Value = wrapper.GetInnerXml(); } } } diff --git a/OneMore/Commands/File/Markdown/MarkdownWriter.cs b/OneMore/Commands/File/Markdown/MarkdownWriter.cs index 7b0207107b..f674cd3538 100644 --- a/OneMore/Commands/File/Markdown/MarkdownWriter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownWriter.cs @@ -364,13 +364,14 @@ private void Stylize(string prefix) } - private void WriteTag(XElement element) + private string WriteTag(XElement element, bool contained) { var symbol = page.Root.Elements(ns + "TagDef") .Where(e => e.Attribute("index").Value == element.Attribute("index").Value) .Select(e => int.Parse(e.Attribute("symbol").Value)) .FirstOrDefault(); - + var retValue = ""; + var tagSymbol = page.taglist.Find(x => x.id == symbol.ToString()); switch (symbol) { case 3: // to do @@ -381,27 +382,15 @@ private void WriteTag(XElement element) case 94: // discuss person a/b case 95: // discuss manager var check = element.Attribute("completed").Value == "true" ? "x" : " "; - writer.Write($"[{check}] "); - break; + retValue = contained + ? @"" + : ($"[{check}] "); - case 6: writer.Write(":question: "); break; // question - case 13: writer.Write(":star: "); break; // important - case 17: writer.Write(":exclamation: "); break; // critical - case 18: writer.Write(":phone: "); break; // phone - case 21: writer.Write(":bulb: "); break; // idea - case 23: writer.Write(":house: "); break; // address - case 33: writer.Write(":three: "); break; // three - case 39: writer.Write(":zero: "); break; // zero - case 51: writer.Write(":two: "); break; // two - case 70: writer.Write(":one: "); break; // one - case 118: writer.Write(":mailbox: "); break; // contact - case 121: writer.Write(":musical_note: "); break; // music to listen to - case 131: writer.Write(":secret: "); break; // password - case 133: writer.Write(":movie_camera: "); break; // movie to see - case 132: writer.Write(":book: "); break; // book to read - case 140: writer.Write(":zap: "); break; // lightning bolt - default: writer.Write(":o: "); break; // big red circle + break; + default: retValue = tagSymbol.name + " "; + break; } + return retValue; } diff --git a/OneMore/Commands/Reminders/RemindCommand.cs b/OneMore/Commands/Reminders/RemindCommand.cs index 74f77dcc9e..73fc7f0cd5 100644 --- a/OneMore/Commands/Reminders/RemindCommand.cs +++ b/OneMore/Commands/Reminders/RemindCommand.cs @@ -226,50 +226,12 @@ private Reminder MakeReminder(OneNote one, XElement paragraph, string objectID) private bool SetReminder(XElement paragraph, Reminder reminder) { - var index = page.GetTagDefIndex(reminder.Symbol); - if (index == null) - { - index = page.AddTagDef(reminder.Symbol, - string.Format(Resx.RemindCommand_nameFormat, reminder.Due.ToFriendlyString())); - - reminder.TagIndex = index; - } - - var tag = paragraph.Elements(ns + "Tag") - .FirstOrDefault(e => e.Attribute("index").Value == index); - - if (tag == null) - { - // tags must be ordered by index even within their containing paragraph - // so take all, remove from paragraph, append, sort, re-add... - - var tags = paragraph.Elements(ns + "Tag").ToList(); - tags.ForEach(t => t.Remove()); - - // synchronize tag with reminder - var completed = reminder.Status == ReminderStatus.Completed - ? "true" : "false"; - - tag = new XElement(ns + "Tag", - new XAttribute("index", index), - new XAttribute("completed", completed), - new XAttribute("disabled", "false") - ); - - tags.Add(tag); - - paragraph.AddFirst(tags.OrderBy(t => t.Attribute("index").Value)); - } - else - { - // synchronize tag with reminder - var tcompleted = tag.Attribute("completed").Value == "true"; - var rcompleted = reminder.Status == ReminderStatus.Completed; - if (tcompleted != rcompleted) - { - tag.Attribute("completed").Value = rcompleted ? "true" : "false"; - } - } + reminder.TagIndex = page.SetTag(paragraph, + tagSymbol: reminder.Symbol, + tagName: string.Format(Resx.RemindCommand_nameFormat, reminder.Due.ToFriendlyString()), + tagStatus : reminder.Status == ReminderStatus.Completed, + tagType: 0 + ); new ReminderSerializer().StoreReminder(page, reminder); diff --git a/OneMore/Models/Page.cs b/OneMore/Models/Page.cs index 0c7b0102bc..5115cd6cbc 100644 --- a/OneMore/Models/Page.cs +++ b/OneMore/Models/Page.cs @@ -28,6 +28,32 @@ internal partial class Page private const string HashAttributeName = "omHash"; + public List<(string name, string id, string topic, int type)> taglist = new List<(string name, string id, string topic, int type)> + { +// (":todo:", "3", "todo" , 0), + (":question:", "6", "question" , 0), + (":star:", "13", "important", 0 ), + (":exclamation:", "17", "critical", 0), + (":phone:", "18", "phone", 0), + (":bulb:", "21", "idea", 0), + (":house:", "23", "address", 0), + (":three:", "33", "three", 0), + (":zero:", "39", "zero", 0), + (":two:", "51", "two", 0), + (":arrow_right:", "59", "main agenda item", 0), + (":one:", "70", "one", 0), + (":information_desk_person:","94", "discuss person a/b", 21), + (":bellsymbol:", "97", "bellsymbol", 0), + (":busts_in_silhouette:", "116", "busts_in_silhouette", 0), + (":bell:", "117", "bell", 0), + (":letter:", "118", "letter", 0), + (":musical_note:", "121", "musical_note", 0), + (":secret:", "131", "idea", 0), + (":book:", "132", "book", 0), + (":movie_camera:", "133", "movie_camera", 0), + (":zap:", "140", "lightning_bolt", 0), + (":o:", "1", "default", 0) + }; /// /// Initialize a new instance with the given page XML root @@ -277,6 +303,55 @@ public void AddTagDef(TagDef tagdef) Root.AddFirst(tagdef); } + /// + /// Extended version from RemindCommand to handle also non Todo Tags + /// + public string SetTag(XElement paragraph, string tagSymbol, string tagName, int tagType = 0, bool tagStatus = false) + { + var index = this.GetTagDefIndex(tagSymbol); + if (index == null) + { + index = this.AddTagDef(tagSymbol, tagName, tagType); + } + + var tag = paragraph.Elements(Namespace + "Tag") + .FirstOrDefault(e => e.Attribute("index").Value == index); + + if (tag == null) + { + // tags must be ordered by index even within their containing paragraph + // so take all, remove from paragraph, append, sort, re-add... + + var tags = paragraph.Elements(Namespace + "Tag").ToList(); + tags.ForEach(t => t.Remove()); + + // synchronize tag with reminder + var completed = tagStatus == true + ? "true" : "false"; + + tag = new XElement(Namespace + "Tag", + new XAttribute("index", index), + new XAttribute("completed", completed), + new XAttribute("disabled", "false") + ); + + tags.Add(tag); + + paragraph.AddFirst(tags.OrderBy(t => t.Attribute("index").Value)); + } + else + { + // synchronize tag with reminder + var tcompleted = tag.Attribute("completed").Value == "true"; + var rcompleted = tagStatus; + if (tcompleted != rcompleted) + { + tag.Attribute("completed").Value = rcompleted ? "true" : "false"; + } + } + return index; + } + /// /// Apply the given quick style mappings to all descendents of the specified outline. From 55000d37d323e1037597b7426d7be1a88cbc58aa Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Tue, 26 Nov 2024 08:06:55 +0100 Subject: [PATCH 03/13] removed adding spaces in each paragraph and moved space handling to styles instead --- OneMore/Commands/Edit/ConvertMarkdownCommand.cs | 5 +++-- OneMore/Styles/StandardStyles.cs | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs index 65d71436fb..46bd5d6680 100644 --- a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs +++ b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs @@ -99,8 +99,9 @@ public override async Task Execute(params object[] args) converter .RewriteHeadings(touched) - .RewriteTodo(touched) - .SpaceOutParagraphs(touched, 12); + .RewriteTodo(touched); +// disabled, as it will space out also short lines. Added space in heading defintion instead +// .SpaceOutParagraphs(touched, 12); await one.Update(page); } diff --git a/OneMore/Styles/StandardStyles.cs b/OneMore/Styles/StandardStyles.cs index 37b15fd01c..79d2521a02 100644 --- a/OneMore/Styles/StandardStyles.cs +++ b/OneMore/Styles/StandardStyles.cs @@ -39,24 +39,32 @@ public static QuickStyleDef GetDefaults(this StandardStyles key) { case StandardStyles.Heading1: style.FontSize = "16.0"; + style.SpaceAfter = "0.5"; + style.SpaceBefore = "0.8"; style.Color = "#1e4e79"; style.StyleType = StyleType.Heading; break; case StandardStyles.Heading2: style.FontSize = "14.0"; + style.SpaceAfter = "0.5"; + style.SpaceBefore = "0.8"; style.Color = "#2e75b5"; style.StyleType = StyleType.Heading; break; case StandardStyles.Heading3: style.FontSize = "12.0"; + style.SpaceAfter = "0.3"; + style.SpaceBefore = "0.3"; style.Color = "#5b9bd5"; style.StyleType = StyleType.Heading; break; case StandardStyles.Heading4: style.FontSize = "12.0"; + style.SpaceAfter = "0.3"; + style.SpaceBefore = "0.3"; style.IsItalic = true; style.Color = "#5b9bd5"; style.StyleType = StyleType.Heading; From 6d3f5f1f48304e0fbf65cb9c34e9709e03f8365c Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Tue, 26 Nov 2024 08:25:40 +0100 Subject: [PATCH 04/13] added fixes to markdown generation added fixes to markdown generation --- .../Commands/File/Markdown/MarkdownWriter.cs | 253 +++++++++++------- 1 file changed, 163 insertions(+), 90 deletions(-) diff --git a/OneMore/Commands/File/Markdown/MarkdownWriter.cs b/OneMore/Commands/File/Markdown/MarkdownWriter.cs index f674cd3538..7dfd9e91b4 100644 --- a/OneMore/Commands/File/Markdown/MarkdownWriter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownWriter.cs @@ -34,18 +34,32 @@ private sealed class Context // accent enclosure char, asterisk* or backquote` public string Accent; } + // helper class to pass parameter + private sealed class PrefixClass + { + public string indents = string.Empty; + public string tags = string.Empty; + public string bullets = string.Empty; + public string tablelistid = string.Empty; + public bool justclosed = false; + + public PrefixClass() + { + } + } // Note that if pasting md text directly into OneNote, there's no good way to indent text // and prevent OneNote from auto-formatting. Closest alt is to use a string of nbsp's // but that conflicts with other directives like headings and list numbering. One way is // to substitute indentations (e.g., OEChildren) with the blockquote directive instead. - private const string Indent = " "; //">"; //    "; + private const string Indent = " "; //">"; //    "; private const string Quote = ">"; private readonly Page page; private readonly XNamespace ns; private readonly List"); + } + } + if (contained) + { + var tableindex = nestedtables.Count() + 1; + nestedtables.Add((element, tableindex)); + writer.Write(prefix.indents + "[nested-table" + tableindex + "](#nested-table" + tableindex + ")"); } - WriteTable(element); + else + { + WriteTable(element, prefix); + while (nestedtables.Count() != 0) + { + var nestedtable = nestedtables.First(); + writer.WriteLine(prefix.indents + "
"); + writer.WriteLine(prefix.indents + "" + "Nested Table " + nestedtable.index + ""); + WriteTable(nestedtable.container, prefix); + writer.WriteLine(prefix.indents + "
"); + nestedtables.RemoveAt(0); + } + } + if (bordersVisible.Equals("true")) + { + writer.Write(prefix.indents + ""); + } + // Write extra line + writer.WriteLine(); break; } } @@ -301,17 +380,7 @@ private void Write(XElement container, private Context DetectQuickStyle(XElement element) { - // quickStyleIndex could be on T, OE, or OEChildren, Outline, Page - // so ascend until we find one... - - int index = -1; - while (element is not null && - !element.GetAttributeValue("quickStyleIndex", out index, -1)) - { - element = element.Parent; - } - - if (index >= 0) + if (element.GetAttributeValue("quickStyleIndex", out int index)) { var context = new Context { @@ -337,30 +406,28 @@ private Context DetectQuickStyle(XElement element) } - private void Stylize(string prefix) + private string Stylize() { - writer.Write(prefix); - if (contexts.Count == 0) return; + var styleprefix = ""; + if (contexts.Count == 0) return ""; var context = contexts.Peek(); var quick = quickStyles.First(q => q.Index == context.QuickStyleIndex); switch (quick.Name) { case "PageTitle": - case "h1": - writer.Write("# "); - break; - - case "h2": writer.Write("## "); break; - case "h3": writer.Write("### "); break; - case "h4": writer.Write("#### "); break; - case "h5": writer.Write("##### "); break; - case "h6": writer.Write("###### "); break; - case "blockquote": writer.Write("> "); break; + case "h1": styleprefix = ("# "); break; + case "h2": styleprefix = ("## "); break; + case "h3": styleprefix = ("### "); break; + case "h4": styleprefix = ("#### "); break; + case "h5": styleprefix = ("##### "); break; + case "h6": styleprefix = ("###### "); break; + case "blockquote": styleprefix = ("> "); break; // cite and code are both block-scope style, on the OE - case "cite": writer.Write("*"); break; - case "code": writer.Write("`"); break; - //case "p": logger.Write(Environment.NewLine); break; + case "cite": styleprefix = ("*"); break; + case "code": styleprefix = ("`"); break; + //case "p": lstyleprefix = (Environment.NewLine); break; } + return styleprefix; } @@ -394,7 +461,7 @@ private string WriteTag(XElement element, bool contained) } - private void WriteText(XCData cdata, bool startOfLine) + private void WriteText(XCData cdata, bool startOfLine, bool contained) { cdata.Value = cdata.Value .Replace("
", " ") // usually followed by NL so leave it there @@ -417,7 +484,15 @@ private void WriteText(XCData cdata, bool startOfLine) span.ReplaceWith(new XText(text)); } - foreach (var anchor in wrapper.Elements("a")) + // escape directives + var raw = wrapper.GetInnerXml() + .Replace("<", "\\<") + .Replace("|", "\\|") + .Replace("à", "→ ") // right arrow + .Replace("\n", contained ? "
" : "\n"); // newlines in tables + + // replace links with <> to allow special characters and hence place if after escape directives + foreach (var anchor in wrapper.Elements("a").ToList()) { var href = anchor.Attribute("href")?.Value; if (!string.IsNullOrEmpty(href)) @@ -429,21 +504,21 @@ private void WriteText(XCData cdata, bool startOfLine) } else { - anchor.ReplaceWith(new XText($"[{anchor.Value}]({href})")); + anchor.ReplaceWith(new XText($"[{anchor.Value}](<{href}>)")); } } } - // escape directives - var raw = wrapper.GetInnerXml() - .Replace("<", "\\<") - .Replace("|", "\\|"); - if (startOfLine && raw.Length > 0 && raw.StartsWith("#")) { writer.Write("\\"); } + if (startOfLine && raw.Length > 0) + { + raw += " "; // add extra space to end of line + } + logger.Debug($"text [{raw}]"); writer.Write(raw); } @@ -469,7 +544,7 @@ private void WriteImage(XElement element) image.Save(filename, ImageFormat.Png); #endif - var imgPath = Path.Combine(attachmentFolder, name); + var imgPath = Path.Combine(attachmentFolder, name).Replace("\\", "/").Replace(" ", "%20"); writer.Write($"![Image-{imageCounter}]({imgPath})"); } else @@ -534,19 +609,16 @@ private void WriteFile(XElement element) } - private void WriteTable(XElement element) + private void WriteTable(XElement element, PrefixClass prefix) { #region WriteRow(TableRow row) void WriteRow(TableRow row) { - writer.Write("| "); + writer.Write(prefix.indents + "| "); foreach (var cell in row.Cells) { - cell.Root - .Element(ns + "OEChildren") - .Elements(ns + "OE") - .ForEach(e => Write(e, contained: true)); - + PrefixClass nestedprefix = new PrefixClass(); + Write(cell.Root, nestedprefix, contained: true); writer.Write(" | "); } writer.WriteLine(); @@ -555,14 +627,15 @@ void WriteRow(TableRow row) var table = new Table(element); - // table needs a blank line before it + // table needs a blank line before it, even 2nd one sometimes needed + writer.WriteLine(); writer.WriteLine(); var rows = table.Rows; // header - - - - - - - - - - - - - - - - - - - - if (table.HasHeaderRow && rows.Any()) + if ((table.HasHeaderRow && rows.Any()) || rows.Count() == 1) { // use first row data as header WriteRow(rows.First()); @@ -582,7 +655,7 @@ void WriteRow(TableRow row) // separator - - - - - - - - - - - - - - - - - - writer.Write("|"); + writer.Write(prefix.indents + "| "); for (int i = 0; i < table.ColumnCount; i++) { writer.Write(" :--- |"); From 14d4621585efa076604fedc667400cb34335f3ab Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Tue, 26 Nov 2024 08:26:14 +0100 Subject: [PATCH 05/13] added selective UseEmojiAndSmiley to allow seperate tag handling --- .../File/Markdown/OneMoreDigExtensions.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs b/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs index 42ab906fd7..ec97b79874 100644 --- a/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs +++ b/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs @@ -5,13 +5,33 @@ namespace River.OneMoreAddIn.Commands { using Markdig; - + using Markdig.Extensions.Emoji; + using System.Collections.Generic; + using System.Linq; + using River.OneMoreAddIn.Helpers.Office; + using System.Web.UI.WebControls; internal static class OneMoreDigExtensions { + public static MarkdownPipelineBuilder UseOneMoreExtensions( this MarkdownPipelineBuilder pipeline) { + var emojiDic = EmojiMapping.GetDefaultEmojiShortcodeToUnicode(); + var emojiDicNew = new Dictionary(); + foreach (var mappings in emojiDic) + { + var tagName = Models.Page.taglist.FirstOrDefault(x => x.name.Equals(mappings.Key)).name; + if (tagName.IsNullOrEmpty()) + { + emojiDicNew.Add(mappings.Key,mappings.Value); + } + } + var DefaultEmojisAndSmileysMapping = new EmojiMapping( + emojiDicNew, EmojiMapping.GetDefaultSmileyToEmojiShortcode()); + // var emojiMapping = EmojiMapping.DefaultEmojisAndSmileysMapping; + pipeline.Extensions.Add(new EmojiExtension(DefaultEmojisAndSmileysMapping)); + pipeline.Extensions.Add(new OneMoreDigExtension()); return pipeline; } From 94fac5e8f29041e9f6630e1dbf65d54fbdb0a0d9 Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Tue, 26 Nov 2024 08:28:31 +0100 Subject: [PATCH 06/13] Fixed issue in , handling in spaceAfter --- OneMore/Commands/File/Markdown/MarkdownConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OneMore/Commands/File/Markdown/MarkdownConverter.cs b/OneMore/Commands/File/Markdown/MarkdownConverter.cs index 607f8954c6..9325630ff2 100644 --- a/OneMore/Commands/File/Markdown/MarkdownConverter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownConverter.cs @@ -240,7 +240,7 @@ public MarkdownConverter SpaceOutParagraphs(float spaceAfter) public MarkdownConverter SpaceOutParagraphs( IEnumerable paragraphs, float spaceAfter) { - var after = $"{spaceAfter:0.0}"; + var after = spaceAfter.ToString("####0.00", CultureInfo.InvariantCulture); var last = paragraphs.Last(); From 30c5ae588fb9b3e6f1ec5191f689d6c0591c8560 Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Thu, 28 Nov 2024 14:16:34 +0100 Subject: [PATCH 07/13] Add RewriteTodo to import MD --- OneMore/Commands/File/ImportCommand.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OneMore/Commands/File/ImportCommand.cs b/OneMore/Commands/File/ImportCommand.cs index 0a0025354a..b2280f6765 100644 --- a/OneMore/Commands/File/ImportCommand.cs +++ b/OneMore/Commands/File/ImportCommand.cs @@ -11,6 +11,7 @@ namespace River.OneMoreAddIn.Commands using System; using System.Drawing; using System.IO; + using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -602,6 +603,7 @@ private async Task ImportMarkdownFile(string filepath, CancellationToken token) converter = new MarkdownConverter(page); converter.RewriteHeadings(); + converter.RewriteTodo(); logger.WriteLine($"updating..."); logger.WriteLine(page.Root); From 8920598ff9af9bb83ac8811482b474a5d81cf1f8 Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Thu, 28 Nov 2024 14:18:12 +0100 Subject: [PATCH 08/13] Moved taglist outside of page class --- .../File/Markdown/MarkdownConverter.cs | 3 +- .../Commands/File/Markdown/MarkdownWriter.cs | 2 +- OneMore/Models/Page.cs | 54 +++++++++---------- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/OneMore/Commands/File/Markdown/MarkdownConverter.cs b/OneMore/Commands/File/Markdown/MarkdownConverter.cs index 9325630ff2..9a4790be75 100644 --- a/OneMore/Commands/File/Markdown/MarkdownConverter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownConverter.cs @@ -7,6 +7,7 @@ namespace River.OneMoreAddIn.Commands using River.OneMoreAddIn.Models; using River.OneMoreAddIn.Styles; using System.Collections.Generic; + using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using System.Xml.Linq; @@ -195,7 +196,7 @@ public MarkdownConverter RewriteTodo(IEnumerable paragraphs) else { // look for all other tags - foreach (var t in page.taglist) + foreach (var t in Page.taglist) { // check for other tags if (text.Value.Contains(t.name)) diff --git a/OneMore/Commands/File/Markdown/MarkdownWriter.cs b/OneMore/Commands/File/Markdown/MarkdownWriter.cs index 7dfd9e91b4..b3273e2c8f 100644 --- a/OneMore/Commands/File/Markdown/MarkdownWriter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownWriter.cs @@ -438,7 +438,7 @@ private string WriteTag(XElement element, bool contained) .Select(e => int.Parse(e.Attribute("symbol").Value)) .FirstOrDefault(); var retValue = ""; - var tagSymbol = page.taglist.Find(x => x.id == symbol.ToString()); + var tagSymbol = Page.taglist.Find(x => x.id == symbol.ToString()); switch (symbol) { case 3: // to do diff --git a/OneMore/Models/Page.cs b/OneMore/Models/Page.cs index 5115cd6cbc..a06df81b63 100644 --- a/OneMore/Models/Page.cs +++ b/OneMore/Models/Page.cs @@ -28,33 +28,6 @@ internal partial class Page private const string HashAttributeName = "omHash"; - public List<(string name, string id, string topic, int type)> taglist = new List<(string name, string id, string topic, int type)> - { -// (":todo:", "3", "todo" , 0), - (":question:", "6", "question" , 0), - (":star:", "13", "important", 0 ), - (":exclamation:", "17", "critical", 0), - (":phone:", "18", "phone", 0), - (":bulb:", "21", "idea", 0), - (":house:", "23", "address", 0), - (":three:", "33", "three", 0), - (":zero:", "39", "zero", 0), - (":two:", "51", "two", 0), - (":arrow_right:", "59", "main agenda item", 0), - (":one:", "70", "one", 0), - (":information_desk_person:","94", "discuss person a/b", 21), - (":bellsymbol:", "97", "bellsymbol", 0), - (":busts_in_silhouette:", "116", "busts_in_silhouette", 0), - (":bell:", "117", "bell", 0), - (":letter:", "118", "letter", 0), - (":musical_note:", "121", "musical_note", 0), - (":secret:", "131", "idea", 0), - (":book:", "132", "book", 0), - (":movie_camera:", "133", "movie_camera", 0), - (":zap:", "140", "lightning_bolt", 0), - (":o:", "1", "default", 0) - }; - /// /// Initialize a new instance with the given page XML root /// @@ -148,6 +121,33 @@ public void OptimizeForSave(bool keep) public bool IsValid => Root is not null; + public static List<(string name, string id, string topic, int type)> taglist = new List<(string name, string id, string topic, int type)> + { +// (":todo:", "3", "todo" , 0), + (":question:", "6", "question" , 0), + (":star:", "13", "important", 0 ), + (":exclamation:", "17", "critical", 0), + (":phone:", "18", "phone", 0), + (":bulb:", "21", "idea", 0), + (":house:", "23", "address", 0), + (":three:", "33", "three", 0), + (":zero:", "39", "zero", 0), + (":two:", "51", "two", 0), + (":arrow_right:", "59", "main agenda item", 0), + (":one:", "70", "one", 0), + (":information_desk_person:","94", "discuss person a/b", 21), + (":bellsymbol:", "97", "bellsymbol", 0), + (":busts_in_silhouette:", "116", "busts_in_silhouette", 0), + (":bell:", "117", "bell", 0), + (":letter:", "118", "letter", 0), + (":musical_note:", "121", "musical_note", 0), + (":secret:", "131", "idea", 0), + (":book:", "132", "book", 0), + (":movie_camera:", "133", "movie_camera", 0), + (":zap:", "140", "lightning_bolt", 0), + (":o:", "1", "default", 0) + }; + /// /// Gets the namespace used to create new elements for the page From 0a12bd315f36e1f7a0bd726417a2a2b45d7c8e4c Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Mon, 23 Dec 2024 10:54:41 +0100 Subject: [PATCH 09/13] reset to original, i.e. removed addition of space setting in default quickstyle --- OneMore/Styles/StandardStyles.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/OneMore/Styles/StandardStyles.cs b/OneMore/Styles/StandardStyles.cs index 79d2521a02..37b15fd01c 100644 --- a/OneMore/Styles/StandardStyles.cs +++ b/OneMore/Styles/StandardStyles.cs @@ -39,32 +39,24 @@ public static QuickStyleDef GetDefaults(this StandardStyles key) { case StandardStyles.Heading1: style.FontSize = "16.0"; - style.SpaceAfter = "0.5"; - style.SpaceBefore = "0.8"; style.Color = "#1e4e79"; style.StyleType = StyleType.Heading; break; case StandardStyles.Heading2: style.FontSize = "14.0"; - style.SpaceAfter = "0.5"; - style.SpaceBefore = "0.8"; style.Color = "#2e75b5"; style.StyleType = StyleType.Heading; break; case StandardStyles.Heading3: style.FontSize = "12.0"; - style.SpaceAfter = "0.3"; - style.SpaceBefore = "0.3"; style.Color = "#5b9bd5"; style.StyleType = StyleType.Heading; break; case StandardStyles.Heading4: style.FontSize = "12.0"; - style.SpaceAfter = "0.3"; - style.SpaceBefore = "0.3"; style.IsItalic = true; style.Color = "#5b9bd5"; style.StyleType = StyleType.Heading; From a8e1a47fa6c2216e6013e00bdfc6f04664f83262 Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Mon, 23 Dec 2024 14:28:45 +0100 Subject: [PATCH 10/13] reverted back spaceoutparagraph --- OneMore/Commands/Edit/ConvertMarkdownCommand.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs index 46bd5d6680..65d71436fb 100644 --- a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs +++ b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs @@ -99,9 +99,8 @@ public override async Task Execute(params object[] args) converter .RewriteHeadings(touched) - .RewriteTodo(touched); -// disabled, as it will space out also short lines. Added space in heading defintion instead -// .SpaceOutParagraphs(touched, 12); + .RewriteTodo(touched) + .SpaceOutParagraphs(touched, 12); await one.Update(page); } From ed2337295c4eec5fd1349058f5a242901b48df5b Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Mon, 23 Dec 2024 14:29:35 +0100 Subject: [PATCH 11/13] Added spacebefore/after handling in markdown (instead of using default setting) --- .../File/Markdown/MarkdownConverter.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/OneMore/Commands/File/Markdown/MarkdownConverter.cs b/OneMore/Commands/File/Markdown/MarkdownConverter.cs index 9a4790be75..e5bcde83d9 100644 --- a/OneMore/Commands/File/Markdown/MarkdownConverter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownConverter.cs @@ -52,6 +52,30 @@ public void RewriteHeadings() { RewriteHeadings(outline.Descendants(ns + "OE")); } + + // added header spacing specific to markdown + var quickstyles = page.Root.Elements(ns + "QuickStyleDef"); + foreach (var quickstyle in quickstyles) + { + var name = quickstyle.Attribute("name").Value; + if (name.Equals("h1") || name.Equals("h2")) + { + replaceAtributes(quickstyle, spaceBefore: 0.8, spaceAfter: 0.5); + } + else + if (name.Equals("h3") || name.Equals("h4")) + { + replaceAtributes(quickstyle, spaceBefore: 0.3, spaceAfter: 0.3); + } + } + void replaceAtributes(XElement quickstyle, double spaceBefore, double spaceAfter) + { + quickstyle.Attributes().Where(a => a.Name == "spaceBefore").Remove(); + quickstyle.SetAttributeValue("spaceBefore", spaceBefore.ToString("####0.00", CultureInfo.InvariantCulture)); + quickstyle.Attributes().Where(a => a.Name == "spaceAfter").Remove(); + quickstyle.SetAttributeValue("spaceAfter", spaceAfter.ToString("####0.00", CultureInfo.InvariantCulture)); + } + } From ed05c5c8345f30bfa518bd0b067e5bd45990547a Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Mon, 23 Dec 2024 18:50:51 +0100 Subject: [PATCH 12/13] Removed uncessary attribute removal --- OneMore/Commands/File/Markdown/MarkdownConverter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OneMore/Commands/File/Markdown/MarkdownConverter.cs b/OneMore/Commands/File/Markdown/MarkdownConverter.cs index e5bcde83d9..1c7e953c09 100644 --- a/OneMore/Commands/File/Markdown/MarkdownConverter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownConverter.cs @@ -70,9 +70,7 @@ public void RewriteHeadings() } void replaceAtributes(XElement quickstyle, double spaceBefore, double spaceAfter) { - quickstyle.Attributes().Where(a => a.Name == "spaceBefore").Remove(); quickstyle.SetAttributeValue("spaceBefore", spaceBefore.ToString("####0.00", CultureInfo.InvariantCulture)); - quickstyle.Attributes().Where(a => a.Name == "spaceAfter").Remove(); quickstyle.SetAttributeValue("spaceAfter", spaceAfter.ToString("####0.00", CultureInfo.InvariantCulture)); } From 24f15dbd5540b073bdeab9cdf5d1c3b566432dcc Mon Sep 17 00:00:00 2001 From: Matthias Weiss Date: Tue, 24 Dec 2024 08:08:56 +0100 Subject: [PATCH 13/13] Moved MarkdownEmojis into own class and file --- .../File/Markdown/MarkdownConverter.cs | 2 +- .../Commands/File/Markdown/MarkdownEmojis.cs | 36 +++++++++++++++++++ .../Commands/File/Markdown/MarkdownWriter.cs | 2 +- .../File/Markdown/OneMoreDigExtensions.cs | 4 +-- OneMore/Models/Page.cs | 28 --------------- OneMore/OneMore.csproj | 1 + 6 files changed, 40 insertions(+), 33 deletions(-) create mode 100644 OneMore/Commands/File/Markdown/MarkdownEmojis.cs diff --git a/OneMore/Commands/File/Markdown/MarkdownConverter.cs b/OneMore/Commands/File/Markdown/MarkdownConverter.cs index 1c7e953c09..05038b4770 100644 --- a/OneMore/Commands/File/Markdown/MarkdownConverter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownConverter.cs @@ -218,7 +218,7 @@ public MarkdownConverter RewriteTodo(IEnumerable paragraphs) else { // look for all other tags - foreach (var t in Page.taglist) + foreach (var t in MarkdownEmojis.taglist) { // check for other tags if (text.Value.Contains(t.name)) diff --git a/OneMore/Commands/File/Markdown/MarkdownEmojis.cs b/OneMore/Commands/File/Markdown/MarkdownEmojis.cs new file mode 100644 index 0000000000..93f2eff2c3 --- /dev/null +++ b/OneMore/Commands/File/Markdown/MarkdownEmojis.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +namespace River.OneMoreAddIn.Commands +{ + public static class MarkdownEmojis + { + public static List<(string name, string id, string topic, int type)> taglist = new List<(string name, string id, string topic, int type)> + { +// (":todo:", "3", "todo" , 0), + (":question:", "6", "question" , 0), + (":star:", "13", "important", 0 ), + (":exclamation:", "17", "critical", 0), + (":phone:", "18", "phone", 0), + (":bulb:", "21", "idea", 0), + (":house:", "23", "address", 0), + (":three:", "33", "three", 0), + (":zero:", "39", "zero", 0), + (":two:", "51", "two", 0), + (":arrow_right:", "59", "main agenda item", 0), + (":one:", "70", "one", 0), + (":information_desk_person:","94", "discuss person a/b", 21), + (":bellsymbol:", "97", "bellsymbol", 0), + (":busts_in_silhouette:", "116", "busts_in_silhouette", 0), + (":bell:", "117", "bell", 0), + (":letter:", "118", "letter", 0), + (":musical_note:", "121", "musical_note", 0), + (":secret:", "131", "idea", 0), + (":book:", "132", "book", 0), + (":movie_camera:", "133", "movie_camera", 0), + (":zap:", "140", "lightning_bolt", 0), + (":o:", "1", "default", 0) + }; + + + } +} diff --git a/OneMore/Commands/File/Markdown/MarkdownWriter.cs b/OneMore/Commands/File/Markdown/MarkdownWriter.cs index b3273e2c8f..197cded54f 100644 --- a/OneMore/Commands/File/Markdown/MarkdownWriter.cs +++ b/OneMore/Commands/File/Markdown/MarkdownWriter.cs @@ -438,7 +438,7 @@ private string WriteTag(XElement element, bool contained) .Select(e => int.Parse(e.Attribute("symbol").Value)) .FirstOrDefault(); var retValue = ""; - var tagSymbol = Page.taglist.Find(x => x.id == symbol.ToString()); + var tagSymbol = MarkdownEmojis.taglist.Find(x => x.id == symbol.ToString()); switch (symbol) { case 3: // to do diff --git a/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs b/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs index ec97b79874..ce83ef85f9 100644 --- a/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs +++ b/OneMore/Commands/File/Markdown/OneMoreDigExtensions.cs @@ -8,8 +8,6 @@ namespace River.OneMoreAddIn.Commands using Markdig.Extensions.Emoji; using System.Collections.Generic; using System.Linq; - using River.OneMoreAddIn.Helpers.Office; - using System.Web.UI.WebControls; internal static class OneMoreDigExtensions { @@ -21,7 +19,7 @@ public static MarkdownPipelineBuilder UseOneMoreExtensions( var emojiDicNew = new Dictionary(); foreach (var mappings in emojiDic) { - var tagName = Models.Page.taglist.FirstOrDefault(x => x.name.Equals(mappings.Key)).name; + var tagName = MarkdownEmojis.taglist.FirstOrDefault(x => x.name.Equals(mappings.Key)).name; if (tagName.IsNullOrEmpty()) { emojiDicNew.Add(mappings.Key,mappings.Value); diff --git a/OneMore/Models/Page.cs b/OneMore/Models/Page.cs index a06df81b63..76b1bce02f 100644 --- a/OneMore/Models/Page.cs +++ b/OneMore/Models/Page.cs @@ -121,34 +121,6 @@ public void OptimizeForSave(bool keep) public bool IsValid => Root is not null; - public static List<(string name, string id, string topic, int type)> taglist = new List<(string name, string id, string topic, int type)> - { -// (":todo:", "3", "todo" , 0), - (":question:", "6", "question" , 0), - (":star:", "13", "important", 0 ), - (":exclamation:", "17", "critical", 0), - (":phone:", "18", "phone", 0), - (":bulb:", "21", "idea", 0), - (":house:", "23", "address", 0), - (":three:", "33", "three", 0), - (":zero:", "39", "zero", 0), - (":two:", "51", "two", 0), - (":arrow_right:", "59", "main agenda item", 0), - (":one:", "70", "one", 0), - (":information_desk_person:","94", "discuss person a/b", 21), - (":bellsymbol:", "97", "bellsymbol", 0), - (":busts_in_silhouette:", "116", "busts_in_silhouette", 0), - (":bell:", "117", "bell", 0), - (":letter:", "118", "letter", 0), - (":musical_note:", "121", "musical_note", 0), - (":secret:", "131", "idea", 0), - (":book:", "132", "book", 0), - (":movie_camera:", "133", "movie_camera", 0), - (":zap:", "140", "lightning_bolt", 0), - (":o:", "1", "default", 0) - }; - - /// /// Gets the namespace used to create new elements for the page /// diff --git a/OneMore/OneMore.csproj b/OneMore/OneMore.csproj index e4d923395f..f81bf26f36 100644 --- a/OneMore/OneMore.csproj +++ b/OneMore/OneMore.csproj @@ -147,6 +147,7 @@ +