From cd176230e9d89dd63c0cf0047c0aa76dd36cce16 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 31 Dec 2024 09:54:20 -0500 Subject: [PATCH] Paste text with CRLF as hard-breaks, paragraphs (#1746) * Paste text with CRLF as hard-breaks, paragraphs #1745 * simplify PageEditor async requirements #1745 --- .../Commands/Edit/ConvertMarkdownCommand.cs | 2 +- .../Commands/Edit/CopyAsMarkdownCommand.cs | 2 +- OneMore/Commands/Edit/PasteTextCommand.cs | 58 ++++++++++--------- .../Commands/Edit/PreviewMarkdownCommand.cs | 2 +- .../Commands/Page/ExtractContentCommand.cs | 2 +- OneMore/Commands/Snippets/InsertBoxCommand.cs | 4 +- .../Commands/Snippets/InsertInfoBoxCommand.cs | 4 +- OneMore/Models/PageEditor.cs | 13 ++--- 8 files changed, 46 insertions(+), 41 deletions(-) diff --git a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs index 00afbfacdd..6c481de5c3 100644 --- a/OneMore/Commands/Edit/ConvertMarkdownCommand.cs +++ b/OneMore/Commands/Edit/ConvertMarkdownCommand.cs @@ -47,7 +47,7 @@ public override async Task Execute(params object[] args) foreach (var outline in outlines.ToList()) { - var content = await editor.ExtractSelectedContent(outline); + var content = editor.ExtractSelectedContent(outline); logger.Debug("outline - - - - - - - - - - - - - - - - - - - - - -"); logger.Debug(content); logger.Debug("/outline"); diff --git a/OneMore/Commands/Edit/CopyAsMarkdownCommand.cs b/OneMore/Commands/Edit/CopyAsMarkdownCommand.cs index c42bc102aa..d2e617c2fc 100644 --- a/OneMore/Commands/Edit/CopyAsMarkdownCommand.cs +++ b/OneMore/Commands/Edit/CopyAsMarkdownCommand.cs @@ -25,7 +25,7 @@ public override async Task Execute(params object[] args) #region WriteMarkdown(PageEditor editor, MarkdownWriter writer, XElement start) async void WriteMarkdown(PageEditor editor, MarkdownWriter writer, XElement start) { - var content = await editor.ExtractSelectedContent(start); + var content = editor.ExtractSelectedContent(start); logger.Debug("markdown content"); logger.Debug(content); diff --git a/OneMore/Commands/Edit/PasteTextCommand.cs b/OneMore/Commands/Edit/PasteTextCommand.cs index f29e028951..fc41b8810e 100644 --- a/OneMore/Commands/Edit/PasteTextCommand.cs +++ b/OneMore/Commands/Edit/PasteTextCommand.cs @@ -1,5 +1,5 @@ //************************************************************************************************ -// Copyright © 2022 Steven M Cohn. All rights reserved. +// Copyright © 2022 Steven M Cohn. All rights reserved. //************************************************************************************************ namespace River.OneMoreAddIn.Commands @@ -23,44 +23,50 @@ public PasteTextCommand() public override async Task Execute(params object[] args) { - await using var one = new OneNote(out var page, out var ns); - var elements = page.Root.Descendants(ns + "T") - .Where(e => e.Attribute("selected")?.Value == "all"); - var text = await new ClipboardProvider().GetText(); if (string.IsNullOrEmpty(text)) { return; } - var editor = new PageEditor(page); - var content = new XElement(ns + "T", new XCData(text)); + await using var one = new OneNote(out var page, out var ns); + PageNamespace.Set(ns); - if (!elements.Any()) + var elements = page.Root.Descendants(ns + "T") + .Where(e => e.Attribute("selected")?.Value == "all"); + + var editor = new PageEditor(page) { - // empty page so add new content - editor.AddNextParagraph(content); - } - else if (elements.Count() > 1) + KeepSelected = false + }; + + if (elements.Any()) { - // selected multiple runs so replace them all - editor.ReplaceSelectedWith(content); + editor.ExtractSelectedContent(); } - else + + // OneNote transforms \r\n into soft-break
but we want hard-breaks, + // so split text into lines... + + var lines = text.Split(new string[] { "\r\n" }, System.StringSplitOptions.None); + + XElement first = null; + for (var i = lines.Length - 1; i >= 0; i--) { - var line = elements.First(); - if (line.Value.Length == 0) - { - // empty cdata, unselected cursor so just insert - line.GetCData().Value = text; - } - else - { - // something is selected so replace it - editor.ReplaceSelectedWith(content); - } + var run = new XElement(ns + "T", new XCData(lines[i])); + first ??= run; + + editor.InsertAtAnchor(run); } + // position insertion cursor after last line... + + page.Root.DescendantNodes().OfType() + .Where(a => a.Name == "selected") + .Remove(); + + first?.SetAttributeValue("selected", "all"); + await one.Update(page); } } diff --git a/OneMore/Commands/Edit/PreviewMarkdownCommand.cs b/OneMore/Commands/Edit/PreviewMarkdownCommand.cs index df20343751..f311debe1c 100644 --- a/OneMore/Commands/Edit/PreviewMarkdownCommand.cs +++ b/OneMore/Commands/Edit/PreviewMarkdownCommand.cs @@ -42,7 +42,7 @@ public override async Task Execute(params object[] args) // collect all outlines on page, in document-order foreach (var outline in page.BodyOutlines) { - var content = await editor.ExtractSelectedContent(outline); + var content = editor.ExtractSelectedContent(outline); if (content != null) { if (paragraphs.Count >= 1) diff --git a/OneMore/Commands/Page/ExtractContentCommand.cs b/OneMore/Commands/Page/ExtractContentCommand.cs index 091bde6dd2..02e56e70fe 100644 --- a/OneMore/Commands/Page/ExtractContentCommand.cs +++ b/OneMore/Commands/Page/ExtractContentCommand.cs @@ -61,7 +61,7 @@ public override async Task Execute(params object[] args) } var editor = new PageEditor(page); - var content = await editor.ExtractSelectedContent(); + var content = editor.ExtractSelectedContent(); var sectionEditor = new SectionEditor(await one.GetSection()); diff --git a/OneMore/Commands/Snippets/InsertBoxCommand.cs b/OneMore/Commands/Snippets/InsertBoxCommand.cs index d772d2e4c6..6e9fe6e702 100644 --- a/OneMore/Commands/Snippets/InsertBoxCommand.cs +++ b/OneMore/Commands/Snippets/InsertBoxCommand.cs @@ -116,7 +116,7 @@ public override async Task Execute(params object[] args) cell.SetContent(MakeDefaultContent(addTitle)); var editor = new PageEditor(page); - await editor.ExtractSelectedContent(); + editor.ExtractSelectedContent(); var box = new XElement(ns + "OE", table.Root); if (editor.Anchor.Name.LocalName.In("OE", "HTMLBlock")) @@ -137,7 +137,7 @@ public override async Task Execute(params object[] args) KeepSelected = true }; - var content = await editor.ExtractSelectedContent(); + var content = editor.ExtractSelectedContent(); if (!content.HasElements) { diff --git a/OneMore/Commands/Snippets/InsertInfoBoxCommand.cs b/OneMore/Commands/Snippets/InsertInfoBoxCommand.cs index b878f963d0..16376a3e66 100644 --- a/OneMore/Commands/Snippets/InsertInfoBoxCommand.cs +++ b/OneMore/Commands/Snippets/InsertInfoBoxCommand.cs @@ -69,7 +69,7 @@ public override async Task Execute(params object[] args) )); var editor = new PageEditor(page); - await editor.ExtractSelectedContent(); + editor.ExtractSelectedContent(); anchor = editor.Anchor; } else @@ -80,7 +80,7 @@ public override async Task Execute(params object[] args) KeepSelected = true }; - content = await editor.ExtractSelectedContent(); + content = editor.ExtractSelectedContent(); anchor = editor.Anchor; editor.Deselect(); diff --git a/OneMore/Models/PageEditor.cs b/OneMore/Models/PageEditor.cs index b12953e05c..181fda47ed 100644 --- a/OneMore/Models/PageEditor.cs +++ b/OneMore/Models/PageEditor.cs @@ -9,7 +9,6 @@ namespace River.OneMoreAddIn.Models using System.Collections.Generic; using System.Linq; using System.Text; - using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; @@ -637,7 +636,7 @@ public bool EditNode(XElement cursor, Func edit) /// Default is to process all page content. /// /// An OEChildren XElement - public async Task ExtractSelectedContent(XElement targetOutline = null) + public XElement ExtractSelectedContent(XElement targetOutline = null) { schema = new PageSchema(); @@ -694,7 +693,7 @@ public async Task ExtractSelectedContent(XElement targetOutline = null // : Anchor.Elements(ns + "OE").Select(e => e.Attribute("objectID").Value).FirstOrDefault(); //logger.WriteLine($"first anchor ({oid})", Anchor); - var snippets = await ExtractSnippets(runs); + var snippets = ExtractSnippets(runs); RebuildContent(snippets, content); //logger.WriteLine($"content", content); @@ -760,9 +759,8 @@ private XElement WholeTableSelected(XElement cell) } - private async Task> ExtractSnippets(List runs) + private List ExtractSnippets(List runs) { - await using var one = new OneNote(); var tables = new List(); var snippets = new List(); @@ -867,6 +865,7 @@ next is null && if (run.Name.LocalName == "Image" && run.Elements(ns + "CallbackID").FirstOrDefault() is XElement callback) { + using var one = new OneNote(); var data = one.GetPageContent(page.PageId, callback.Attribute("callbackID").Value); @@ -1078,9 +1077,9 @@ private void CleanupOrphanedElements() } - public async Task ReplaceSelectedContent(XElement replacement) + public bool ReplaceSelectedContent(XElement replacement) { - var content = await ExtractSelectedContent(); + var content = ExtractSelectedContent(); if (!content.HasElements) {