Skip to content

Commit d83b6c9

Browse files
authored
Release 3.3.2
2 parents 7e9046e + 9787f10 commit d83b6c9

12 files changed

Lines changed: 159 additions & 40 deletions

File tree

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "coreclr",
77
"request": "launch",
88
"preLaunchTask": "",
9-
"program": "${workspaceRoot}/examples/Demo/bin/Debug/net8.0/Demo.dll",
9+
"program": "${workspaceRoot}/examples/Demo/bin/Debug/net10.0/Demo.dll",
1010
"args": [],
1111
"cwd": "${workspaceRoot}/examples/Demo/",
1212
"stopAtEntry": false

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 3.3.2
4+
5+
- Supports Greek numbering in ordered lists (upper-greek / lower-greek) #227
6+
- Fix nested table in list not filing the full width space #225
7+
- Fix remove extra whitespace when parsing nested span #224
8+
39
## 3.3.1
410

511
- Improve parsing to correctly handle spaces in css style #222

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<Nullable>enable</Nullable>
55
<LangVersion>latest</LangVersion>
66
<ImplicitUsings>enable</ImplicitUsings>
7-
<Version>3.3.1</Version>
7+
<Version>3.3.2</Version>
88
</PropertyGroup>
99

1010
<PropertyGroup>

examples/Demo/Demo.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<OutputType>Exe</OutputType>
66
<SonarQubeExclude>true</SonarQubeExclude>
77
</PropertyGroup>
88

99
<ItemGroup>
1010
<PackageReference Include="DocumentFormat.OpenXml" Version="$(DocumentFormatOpenXmlPackageVersion)" />
11-
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
1211
</ItemGroup>
1312

1413
<ItemGroup>

examples/Demo/Program.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
using System;
2-
using System.IO;
3-
using System.Diagnostics;
1+
using System.Diagnostics;
42
using DocumentFormat.OpenXml;
53
using DocumentFormat.OpenXml.Packaging;
64
using DocumentFormat.OpenXml.Validation;
75
using DocumentFormat.OpenXml.Wordprocessing;
86
using HtmlToOpenXml;
9-
using System.Threading.Tasks;
107

118
namespace Demo
129
{
@@ -18,7 +15,7 @@ static async Task Main(string[] args)
1815
string html = ResourceHelper.GetString("Resources.CompleteRunTest.html");
1916
if (File.Exists(filename)) File.Delete(filename);
2017

21-
using (MemoryStream generatedDocument = new MemoryStream())
18+
using (MemoryStream generatedDocument = new())
2219
{
2320
// Uncomment and comment the second using() to open an existing template document
2421
// instead of creating it from scratch.

examples/Demo/Resources/CompleteRunTest.html

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,34 @@ <h5>Heading 5</h5>
154154
<li>Wine</li>
155155
</ol>
156156

157+
<p>An Ordered List with Greek numbering: </p>
158+
<ol style="list-style-type: upper-greek">
159+
<li>alpha</li>
160+
<li>
161+
beta
162+
<ol style="list-style-type: lower-greek">
163+
<li>two.one</li>
164+
<li>two.two</li>
165+
<li>two.three</li>
166+
</ol>
167+
</li>
168+
169+
<li>
170+
three
171+
<ol style="list-style-type: lower-greek">
172+
<li>three.one</li>
173+
<li>
174+
three.two
175+
<ol>
176+
<li>three.two.one</li>
177+
<li>three.two.two</li>
178+
</ol>
179+
</li>
180+
</ol>
181+
</li>
182+
<li>four</li>
183+
</ol>
184+
157185
<table border=1><tr><td>Inside table</td></tr></table>
158186
<hr />
159187
<p>delta parameter (<span style='font-family:Symbol'>d</span>)</p>

examples/Demo/Resources/NumberingList.htm

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,30 @@
7878
</li>
7979
<li>four</li>
8080
</ol>
81+
82+
<ol style="list-style-type: upper-greek">
83+
<li>one</li>
84+
<li>
85+
two
86+
<ol style="list-style-type: lower-greek">
87+
<li>two.one</li>
88+
<li>two.two</li>
89+
<li>two.three</li>
90+
</ol>
91+
</li>
92+
93+
<li>
94+
three
95+
<ol style="list-style-type: lower-greek">
96+
<li>three.one</li>
97+
<li>
98+
three.two
99+
<ol>
100+
<li>three.two.one</li>
101+
<li>three.two.two</li>
102+
</ol>
103+
</li>
104+
</ol>
105+
</li>
106+
<li>four</li>
107+
</ol>

src/Html2OpenXml/Expressions/Numbering/ListExpression.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ readonly struct ListContext(string listName, int absNumId, int instanceId, int l
4040
private static readonly HashSet<string> supportedListTypes =
4141
["disc", "decimal", "square", "circle",
4242
"lower-alpha", "upper-alpha", "lower-latin", "upper-latin",
43+
"lower-greek", "upper-greek",
4344
"lower-roman", "upper-roman",
4445
"decimal-tiered" /* not W3C compliant */];
4546
private ParagraphStyleId? listParagraphStyleId;
@@ -90,14 +91,14 @@ public override IEnumerable<OpenXmlElement> Interpret(ParsingContext context)
9091

9192
// table must be aligned to the list item
9293
var tables = childElements.OfType<Table>();
93-
var tableIndentation = level * Indentation * 2;
94+
var tableIndentation = level * Indentation;
9495
foreach (var table in tables)
9596
{
9697
var tableProperties = table.GetFirstChild<TableProperties>();
9798
if (tableProperties == null)
9899
table.PrependChild(tableProperties = new());
99100

100-
tableProperties.TableIndentation ??= new() { Width = tableIndentation };
101+
tableProperties.TableIndentation ??= new() { Width = tableIndentation * 2 };
101102
// ensure to restrain the table width to the list item
102103
if (tableProperties.TableWidth?.Type?.Value == TableWidthUnitValues.Pct
103104
&& tableProperties.TableWidth?.Width?.Value == "5000")
@@ -243,6 +244,7 @@ private static string GetListName(IElement listNode, string? parentName = null)
243244
"A" => "upper-alpha",
244245
"i" => "lower-roman",
245246
"I" => "upper-roman",
247+
"lower-greek" or "upper-greek" => type,
246248
_ => null
247249
};
248250

src/Html2OpenXml/Expressions/TextExpression.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ private static ISet<string> InitPhrasingSets()
3333
var sets = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) {
3434
TagNames.A, TagNames.Abbr, TagNames.B, TagNames.Big, TagNames.Cite, TagNames.Code,
3535
TagNames.Del, TagNames.Dfn, TagNames.Em, TagNames.Font, TagNames.Hr, TagNames.I,
36-
TagNames.Img, TagNames.Ins, TagNames.Kbd, TagNames.Mark, TagNames.NoBr, TagNames.Q,
36+
TagNames.Ins, TagNames.Kbd, TagNames.Mark, TagNames.NoBr, TagNames.Q,
3737
TagNames.Rp, TagNames.Rt, TagNames.S, TagNames.Samp, TagNames.Small, TagNames.Span,
3838
TagNames.Strike, TagNames.Strong, TagNames.Sub, TagNames.Sup, TagNames.Time,
3939
TagNames.Tt, TagNames.U, TagNames.Var
@@ -65,50 +65,56 @@ public override IEnumerable<OpenXmlElement> Interpret (ParsingContext context)
6565
// If there is a space between two phrasing elements, the user agent should collapse it to a single space character.
6666
if (context.CollapseWhitespaces)
6767
{
68+
var previousSibling = node.PreviousSibling;
69+
var nextSibling = node.NextSibling;
6870
bool startsWithSpace = text[0].IsWhiteSpaceCharacter(),
6971
endsWithSpace = text[text.Length - 1].IsWhiteSpaceCharacter(),
7072
preserveBorderSpaces = AllPhrasings.Contains(node.Parent!.NodeName),
71-
prevIsPhrasing = node.PreviousSibling is not null &&
72-
(AllPhrasings.Contains(node.PreviousSibling.NodeName) || node.PreviousSibling!.NodeType == NodeType.Text),
73-
nextIsPhrasing = node.NextSibling is not null &&
74-
(AllPhrasings.Contains(node.NextSibling.NodeName) || node.NextSibling!.NodeType == NodeType.Text);
73+
prevIsPhrasing = previousSibling is not null &&
74+
(previousSibling.NodeType == NodeType.Text || AllPhrasings.Contains(previousSibling.NodeName)),
75+
nextIsPhrasing = nextSibling is not null &&
76+
(nextSibling.NodeType == NodeType.Text || AllPhrasings.Contains(nextSibling.NodeName));
7577

7678
text = text.CollapseAndStrip();
7779

7880
// keep a collapsed single space if it stands between 2 phrasings that respect.
7981
// doesn't ends/starts with a whitespace
8082
if (text.Length == 0 && prevIsPhrasing && nextIsPhrasing
8183
&& (endsWithSpace || startsWithSpace)
82-
&& !(node.PreviousSibling!.TextContent.Length == 0
83-
|| node.NextSibling!.TextContent.Length == 0
84-
|| node.PreviousSibling!.TextContent[node.PreviousSibling!.TextContent.Length - 1].IsWhiteSpaceCharacter()
85-
|| node.NextSibling!.TextContent[0].IsWhiteSpaceCharacter()
84+
&& !(previousSibling!.TextContent.Length == 0
85+
|| nextSibling!.TextContent.Length == 0
86+
|| previousSibling!.TextContent[previousSibling!.TextContent.Length - 1].IsWhiteSpaceCharacter()
87+
|| nextSibling!.TextContent[0].IsWhiteSpaceCharacter()
8688
))
8789
{
8890
return [new Run(new Text(" ") { Space = SpaceProcessingModeValues.Preserve })];
8991
}
92+
93+
// is this an inter-element whitespace btw 2 phrasings?
94+
var isWhitespace = text.Length == 0;
95+
9096
// we strip out all whitespaces and we stand inside a div. Just skip this text content
91-
if (text.Length == 0 && !preserveBorderSpaces)
97+
if (isWhitespace && !(prevIsPhrasing && nextIsPhrasing) && !preserveBorderSpaces)
9298
{
9399
return [];
94100
}
95101

96102
// if previous element is an image, append a space separator
97-
if ((startsWithSpace && node.PreviousSibling is IHtmlImageElement)
103+
if ((startsWithSpace && previousSibling is IHtmlImageElement)
98104
// if this is a non-empty phrasing element, append a space separator
99-
|| (startsWithSpace && prevIsPhrasing
100-
&& node.PreviousSibling!.TextContent.Length > 0
101-
&& !node.PreviousSibling!.TextContent[node.PreviousSibling.TextContent.Length - 1].IsWhiteSpaceCharacter()))
105+
|| (!isWhitespace && startsWithSpace && prevIsPhrasing
106+
&& previousSibling!.TextContent.Length > 0
107+
&& !previousSibling!.TextContent[previousSibling.TextContent.Length - 1].IsWhiteSpaceCharacter()))
102108
{
103109
text = " " + text;
104110
}
105111

106-
if (endsWithSpace && (
112+
if (endsWithSpace && !isWhitespace && (
107113
// next run is not starting with a linebreak
108-
(nextIsPhrasing && node.NextSibling!.TextContent.Length > 0 &&
109-
!node.NextSibling!.TextContent[0].IsLineBreak()) ||
114+
(nextIsPhrasing && nextSibling!.TextContent.Length > 0 &&
115+
!nextSibling!.TextContent[0].IsLineBreak()) ||
110116
// if there is no more text element or is empty, eat the trailing space
111-
(preserveBorderSpaces && (node.NextSibling is not null
117+
(preserveBorderSpaces && (nextSibling is not null
112118
|| node.Parent.NextSibling is not null))))
113119
{
114120
text += " ";

test/HtmlToOpenXml.Tests/LinkTests.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,12 @@ public void ImageFigcaptionLink_ReturnsHyperlinkWithTextAndImage ()
6666
Assert.That(elements[0].FirstChild, Is.TypeOf<Hyperlink>());
6767

6868
var hyperlink = (Hyperlink) elements[0].FirstChild;
69-
Assert.That(hyperlink.ChildElements, Has.Count.EqualTo(6));
70-
Assert.That(hyperlink.ChildElements, Has.All.TypeOf<Run>(), "Hyperlinks don't accept inner paragraphs");
71-
Assert.That(hyperlink.Descendants<Drawing>(), Is.Not.Null);
69+
using (Assert.EnterMultipleScope())
70+
{
71+
Assert.That(hyperlink.ChildElements, Has.Count.EqualTo(6));
72+
Assert.That(hyperlink.ChildElements, Has.All.TypeOf<Run>(), "Hyperlinks don't accept inner paragraphs");
73+
Assert.That(hyperlink.Descendants<Drawing>(), Is.Not.Null);
74+
}
7275
}
7376

7477
[Test]

0 commit comments

Comments
 (0)