Skip to content

Commit

Permalink
fix AlterSize to work across outlines (stevencohn#1480)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevencohn authored Jul 15, 2024
1 parent 38a7ecf commit 6e3dbb0
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 40 deletions.
118 changes: 79 additions & 39 deletions OneMore/Commands/Edit/AlterSizeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright © 2018 Steven M Cohn. All rights reserved.
//************************************************************************************************

#pragma warning disable S3267 // Loops should be simplified with "LINQ" expressions

namespace River.OneMoreAddIn.Commands
{
using River.OneMoreAddIn.Models;
Expand Down Expand Up @@ -43,7 +45,7 @@ internal class AlterSizeCommand : Command
private const double MinFontSize = 6.0;
private const double MaxFontSize = 144.0;

private Page page;
private XNamespace ns;
private int delta;


Expand All @@ -56,53 +58,90 @@ public override async Task Execute(params object[] args)
{
delta = (int)args[0]; // +/-1

await using var one = new OneNote(out page, out _);
await using var one = new OneNote(out var page, out ns);

if (page == null)
if (page is null)
{
return;
}

var count
= AlterByName()
+ AlterElementsByValue()
+ AlterCDataByValue();
var count = AlterQuickStyles(page);

if (count == 0)
foreach (var outline in page.Root
.Elements(ns + "Outline")
.Where(e => !e.Elements(ns + "Meta")
.Any(m => m.Attribute("name").Value == MetaNames.TaggingBank)))
{
return;
count +=
AlterByName(outline) +
AlterElementsByValue(outline) +
AlterCDataByValue(outline);
}

await one.Update(page);
if (count > 0)
{
// must force update incase only QuickStyleDefs have changed
await one.Update(page, true);
}
}


private int AlterByName()
public int AlterQuickStyles(Page page)
{
var count = 0;
foreach (var element in page.Root.Elements(ns + "QuickStyleDef")
.Where(e => e.Attribute("name").Value != "PageTitle"))
{
if (element.Attribute("fontSize") is XAttribute attr)
{
if (double.TryParse(attr.Value,
NumberStyles.Any, CultureInfo.InvariantCulture, out var size))
{
var result = delta < 0
? Math.Max(size + delta, MinFontSize)
: Math.Min(size + delta, MaxFontSize);

if (!result.Equalsish(size))
{
attr.Value = $"{result:#0}.05";
count++;
}
}
}
}

return count;
}


private int AlterByName(XElement outline)
{
// find all elements that have an attribute named fontSize, e.g. QuickStyleDef or Bullet
var elements = page.Root.Descendants()
.Where(p =>
p.Attribute("name")?.Value != "PageTitle" &&
p.Attribute("fontSize") != null);
var elements = outline.Descendants()
.Where(p => p.Attribute("fontSize") is not null);

if (!elements.IsNullOrEmpty())
if (elements.IsNullOrEmpty())
{
foreach (var element in elements)
return 0;
}

var count = 0;
foreach (var element in elements)
{
if (element is not null)
{
if (element != null)
if (element.Attribute("fontSize") is XAttribute attr)
{
if (element.Attribute("fontSize") is XAttribute attr)
if (double.TryParse(attr.Value,
NumberStyles.Any, CultureInfo.InvariantCulture, out var size))
{
if (double.TryParse(attr.Value,
NumberStyles.Any, CultureInfo.InvariantCulture, out var size))
{
size = delta < 0
? Math.Max(size + delta, MinFontSize)
: Math.Min(size + delta, MaxFontSize);
var result = delta < 0
? Math.Max(size + delta, MinFontSize)
: Math.Min(size + delta, MaxFontSize);

attr.Value = size.ToString("#0") + ".05";
if (!result.Equalsish(size))
{
attr.Value = $"{result:#0}.05";
count++;
}
}
Expand All @@ -116,14 +155,12 @@ private int AlterByName()

// <one:OE alignment="left" spaceBefore="14.0" quickStyleIndex="1"
// style="font-family:'Segoe UI';font-size:&#xA;20.0pt;color:#151515">
private int AlterElementsByValue()
private int AlterElementsByValue(XElement outline)
{
int count = 0;

var elements = page.Root.Descendants()
.Where(p =>
p.Parent.Name.LocalName != "Title" &&
p.Attribute("style")?.Value.Contains("font-size:") == true);
var elements = outline.Descendants()
.Where(p => p.Attribute("style")?.Value.Contains("font-size:") == true);

if (!elements.IsNullOrEmpty())
{
Expand All @@ -140,11 +177,11 @@ private int AlterElementsByValue()
}


private int AlterCDataByValue()
private int AlterCDataByValue(XElement outline)
{
int count = 0;

var nodes = page.Root.DescendantNodes().OfType<XCData>()
var nodes = outline.DescendantNodes().OfType<XCData>()
.Where(n => n.Value.Contains("font-size:"));

if (!nodes.IsNullOrEmpty())
Expand Down Expand Up @@ -180,7 +217,7 @@ private bool UpdateSpanStyle(XElement span)
bool updated = false;

var attr = span.Attribute("style");
if (attr != null)
if (attr is not null)
{
// remove encoded LF character (&#xA)
var css = attr.Value.Replace("\n", string.Empty);
Expand Down Expand Up @@ -210,16 +247,19 @@ private bool UpdateSpanStyle(XElement span)
{
var size = ParseFontSize(properties["font-size"]);

size = delta < 0
var result = delta < 0
? Math.Max(size + delta, MinFontSize)
: Math.Min(size + delta, MaxFontSize);

properties["font-size"] = size.ToString("#0") + ".05pt";
if (!result.Equalsish(size))
{
properties["font-size"] = $"{result:#0}.05pt";

attr.Value =
string.Join(";", properties.Select(p => p.Key + ":" + p.Value).ToArray());
attr.Value =
string.Join(";", properties.Select(p => p.Key + ":" + p.Value).ToArray());

updated = true;
updated = true;
}
}
}

Expand Down
1 change: 0 additions & 1 deletion OneMore/Commands/Tagging/HashtagDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ namespace River.OneMoreAddIn.Commands
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using Resx = Properties.Resources;


Expand Down
27 changes: 27 additions & 0 deletions OneMore/Helpers/Extensions/DoubleExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//************************************************************************************************
// Copyright © 2024 Steven M Cohn. All rights reserved.
//************************************************************************************************

namespace River.OneMoreAddIn
{
using System;


internal static class DoubleExtensions
{
/// <summary>
/// OneMore Extension >> Compares two Doubles with a specified epsilon window.
/// </summary>
/// <param name="a">This Double</param>
/// <param name="b">That Double</param>
/// <param name="epsilon">
/// The fudge factor for comparison. This defaults to 0.5 which is good for
/// font size comparisons, our most common use case in OneMore
/// </param>
/// <returns>True if the two values are within the specified epsilon difference</returns>
public static bool Equalsish(this double a, double b, double epsilon = 0.5)
{
return Math.Abs(a - b) < epsilon;
}
}
}
1 change: 1 addition & 0 deletions OneMore/OneMore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
<Compile Include="Commands\Tools\QuickPaletteCommand.cs" />
<Compile Include="Helpers\ColorHelper.cs" />
<Compile Include="Helpers\Extensions\ArrayExtensions.cs" />
<Compile Include="Helpers\Extensions\DoubleExtensions.cs" />
<Compile Include="Helpers\Extensions\FontFamilyExtensions.cs" />
<Compile Include="Helpers\Extensions\GraphicsExtensions.cs" />
<Compile Include="Helpers\Extensions\HashAlgorithmExtensions.cs" />
Expand Down

0 comments on commit 6e3dbb0

Please sign in to comment.