Skip to content

Commit 8592c53

Browse files
authored
Merge pull request #182 from onizet/dev
Release 3.2.2
2 parents 7c61538 + 5c6bfe2 commit 8592c53

22 files changed

+415
-144
lines changed

.github/workflows/dotnet.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ on:
1010
- 'docs/**'
1111
- '**/*.md'
1212
pull_request:
13-
branches: [ "dev" ]
1413

1514
jobs:
1615
net8:

CHANGELOG.md

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

3+
## 3.2.2
4+
5+
- Supports a feature to disable heading numbering #175
6+
- Support center image with margin auto #171
7+
- Support deprecrated align attribute for block #171
8+
- Fix parsing of style attribute with a key with no value
9+
- Improve parsing of style attribute to avoid an extra call to HtmlDecode
10+
- Extend support of nested list for non-W3C compliant html #173
11+
- Change way to apply table 100% width
12+
- Allow to apply percentage widths cells
13+
314
## 3.2.1
415

516
- Fix indentation of numbering list #166

HtmlToOpenXml.sln

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,33 @@ EndProject
1414
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlToOpenXml.Tests", "test\HtmlToOpenXml.Tests\HtmlToOpenXml.Tests.csproj", "{CA0A68E0-45A0-4A01-A061-F951D93D6906}"
1515
EndProject
1616
Global
17-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18-
Debug|Any CPU = Debug|Any CPU
19-
Release|Any CPU = Release|Any CPU
20-
EndGlobalSection
21-
GlobalSection(ProjectConfigurationPlatforms) = postSolution
22-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.Build.0 = Debug|Any CPU
24-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.ActiveCfg = Release|Any CPU
25-
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.Build.0 = Release|Any CPU
26-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.Build.0 = Debug|Any CPU
28-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.ActiveCfg = Release|Any CPU
29-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.Build.0 = Release|Any CPU
30-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.Build.0 = Debug|Any CPU
32-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.ActiveCfg = Release|Any CPU
33-
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.Build.0 = Release|Any CPU
34-
EndGlobalSection
35-
GlobalSection(SolutionProperties) = preSolution
36-
HideSolutionNode = FALSE
37-
EndGlobalSection
38-
GlobalSection(NestedProjects) = preSolution
39-
{EF700F30-C9BB-49A6-912C-E3B77857B514} = {58520A98-BA53-4BA4-AAE3-786AA21331D6}
40-
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
41-
{CA0A68E0-45A0-4A01-A061-F951D93D6906} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
42-
EndGlobalSection
43-
GlobalSection(ExtensibilityGlobals) = postSolution
44-
SolutionGuid = {14EE1026-6507-4295-9FEE-67A55C3849CE}
45-
EndGlobalSection
17+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18+
Debug|Any CPU = Debug|Any CPU
19+
Release|Any CPU = Release|Any CPU
20+
EndGlobalSection
21+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
22+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{EF700F30-C9BB-49A6-912C-E3B77857B514}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F}.Release|Any CPU.Build.0 = Release|Any CPU
30+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.ActiveCfg = Release|Any CPU
33+
{CA0A68E0-45A0-4A01-A061-F951D93D6906}.Release|Any CPU.Build.0 = Release|Any CPU
34+
EndGlobalSection
35+
GlobalSection(SolutionProperties) = preSolution
36+
HideSolutionNode = FALSE
37+
EndGlobalSection
38+
GlobalSection(NestedProjects) = preSolution
39+
{EF700F30-C9BB-49A6-912C-E3B77857B514} = {58520A98-BA53-4BA4-AAE3-786AA21331D6}
40+
{A1ECC760-B9F7-4A00-AF5F-568B5FD6F09F} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
41+
{CA0A68E0-45A0-4A01-A061-F951D93D6906} = {84EA02ED-2E97-47D2-992E-32CC104A3A7A}
42+
EndGlobalSection
43+
GlobalSection(ExtensibilityGlobals) = postSolution
44+
SolutionGuid = {14EE1026-6507-4295-9FEE-67A55C3849CE}
45+
EndGlobalSection
4646
EndGlobal

examples/Demo/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,4 @@ static void AssertThatOpenXmlDocumentIsValid(WordprocessingDocument wpDoc)
7474
Console.ReadLine();
7575
}
7676
}
77-
}
77+
}

examples/Demo/Resources/CompleteRunTest.html

Lines changed: 80 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@
44
<title></title>
55
</head>
66
<body>
7+
8+
<table style="width: 100%; border-collapse: collapse; margin: 20px auto; border: 1px solid #ccc;">
9+
<tr style="background-color: #f4f4f4; text-align: left;">
10+
<th style="width: 10%; border: 1px solid #ccc; padding: 8px;">Column 1</th>
11+
<th style="width: 60%; border: 1px solid #ccc; padding: 8px;">Column 2</th>
12+
<th style="width: 30%; border: 1px solid #ccc; padding: 8px;">Column 3</th>
13+
</tr>
14+
<tr>
15+
<td style="width: 10%; border: 1px solid #ccc; padding: 8px;">Row 1, Cell 1</td>
16+
<td style="width: 60%; border: 1px solid #ccc; padding: 8px;">Row 1, Cell 2</td>
17+
<td style="width: 30%; border: 1px solid #ccc; padding: 8px;">Row 1, Cell 3</td>
18+
</tr>
19+
<tr>
20+
<td style="width: 10%; border: 1px solid #ccc; padding: 8px;">Row 2, Cell 1</td>
21+
<td style="width: 60%; border: 1px solid #ccc; padding: 8px;">Row 2, Cell 2</td>
22+
<td style="width: 30%; border: 1px solid #ccc; padding: 8px;">Row 2, Cell 3</td>
23+
</tr>
24+
</table>
25+
726
<h1></h1>
827
<h1>Heading 1</h1>
928
<h2>Heading 2</h2>
@@ -15,8 +34,11 @@ <h5>Heading 5</h5>
1534
<span style="font-variant: small-caps"> Small caps</span><br />
1635
<strike>Strike</strike> <span style="text-decoration: line-through"> Line Through</span> <span style="text-decoration: overline"> Overline</span> <span style="text-decoration: underline"> Underline</span><br />
1736
<b> Bold</b><br />
18-
<span>This is a <b>bold
19-
</b>text</span>
37+
<span>
38+
This is a <b>
39+
bold
40+
</b>text
41+
</span>
2042
<span style="font-weight: bold">Bold</span><br />
2143
<span style="font-weight: bolder">Bolder</span><br />
2244
<span style="font-weight: lighter">Lighter</span><br />
@@ -47,7 +69,8 @@ <h5>Heading 5</h5>
4769
<a href="www.github.com"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" /></a>
4870

4971
<!-- multiline images -->
50-
<p><img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8l
72+
<p>
73+
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8l
5174
JCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/wAALCABVAEABAREA/8QAHwAA
5275
AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR
5376
BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RF
@@ -88,7 +111,8 @@ <h5>Heading 5</h5>
88111
OfDEXhz/AIRbxtAkV1pYNrJHNC0qSbPlDKQDg8e3tVD4Q6BKPGmp67Y2lxbaJ5ckVo04IMgZ
89112
1KjnqAByfXFezMiv95Q2PUZoCKOigY9BSkA9QDjmgqGBDAEHsaia0tnQxtbxMjdVKAg0W9pb
90113
Wilba3ihB6iNAufyoltLaZw8tvFIw6FkBNSgADA4FLRRRRRRRX//2Q==
91-
"></p>
114+
">
115+
</p>
92116

93117
<img src="https://www.w3schools.com/tags/smiley.gif" alt="Smiley face" width="42" height="42">
94118

@@ -102,79 +126,81 @@ <h5>Heading 5</h5>
102126
<br />
103127

104128

105-
<blockquote cite="http://www.worldwildlife.org/who/index.html">
106-
For 50 years, <b>WWF</b> has been protecting the future of nature. The world's leading conservation organization, WWF works in 100 countries and is supported by 1.2 million members in the United States and close to 5 million globally.
107-
</blockquote>
129+
<blockquote cite="http://www.worldwildlife.org/who/index.html">
130+
For 50 years, <b>WWF</b> has been protecting the future of nature. The world's leading conservation organization, WWF works in 100 countries and is supported by 1.2 million members in the United States and close to 5 million globally.
131+
</blockquote>
108132

109-
<br class="ibp-rteFontSize-5"/><span style="font-size: 16.9px">My Text </span>
133+
<br class="ibp-rteFontSize-5" /><span style="font-size: 16.9px">My Text </span>
110134

111-
<p>An ordered list:</p>
135+
<p>An ordered list:</p>
112136
<ol>
113-
<li>Coffee</li>
114-
<li>Tea</li>
115-
<li>Milk
116-
<ul>
117-
<li>Coffee</li>
118-
<li>Tea
119-
<ol>
120-
<li>Earl Grey</li>
121-
<li>Green</li>
122-
<li>Rosboh</li>
123-
</ol>
124-
</li>
125-
<li>Milk</li>
126-
</ul>
127-
</li>
128-
<li>Wine</li>
137+
<li>Coffee</li>
138+
<li>Tea</li>
139+
<li>
140+
Milk
141+
<ul>
142+
<li>Coffee</li>
143+
<li>
144+
Tea
145+
<ol>
146+
<li>Earl Grey</li>
147+
<li>Green</li>
148+
<li>Rosboh</li>
149+
</ol>
150+
</li>
151+
<li>Milk</li>
152+
</ul>
153+
</li>
154+
<li>Wine</li>
129155
</ol>
130156

131-
<table border=1><tr><td>Inside table</td></tr></table>
132-
<hr />
133-
<p>delta parameter (<span style='font-family:Symbol'>d</span>)</p>
134-
Looks how cool is <font size="x-large" color="maroon"><b>Open Xml</b></font>.
135-
<hr />
136-
Now with <font color="red"><u>HtmlToOpenXml</u></font>, it never been so easy to convert html.
137-
<p>
138-
If you like it, add me a rating on <a href="https://github.com/onizet/html2openxml">github</a>
139-
</p>
140-
141-
simple text
142-
<div style="page-orientation: landscape; page-break-before: always">
143-
Hello !
144-
je suis du texte
145-
<span style="font-style: oblique">écrit en oblique.</span>
146-
147-
<pre lang="fr-FR" class="c#"> public void SetContentType(System.Web.HttpRequest request, System.Web.HttpResponse response, String reportName)
157+
<table border=1><tr><td>Inside table</td></tr></table>
158+
<hr />
159+
<p>delta parameter (<span style='font-family:Symbol'>d</span>)</p>
160+
Looks how cool is <font size="x-large" color="maroon"><b>Open Xml</b></font>.
161+
<hr />
162+
Now with <font color="red"><u>HtmlToOpenXml</u></font>, it never been so easy to convert html.
163+
<p>
164+
If you like it, add me a rating on <a href="https://github.com/onizet/html2openxml">github</a>
165+
</p>
166+
167+
simple text
168+
<div style="page-orientation: landscape; page-break-before: always">
169+
Hello !
170+
je suis du texte
171+
<span style="font-style: oblique">écrit en oblique.</span>
172+
173+
<pre lang="fr-FR" class="c#"> public void SetContentType(System.Web.HttpRequest request, System.Web.HttpResponse response, String reportName)
148174
{
149175
if (request.Browser.Browser.Contains(&quot;IE&quot;))
150176
{
151-
<span style="color:Green">// Replace the %20 to obtain a clean name when saving the file from Word.</span>
177+
<span style="color:Green">// Replace the %20 to obtain a clean name when saving the file from Word.</span>
152178
encodedFilename =
153179
Uri.EscapeDataString(Path.GetFileNameWithoutExtension(encodedFilename)).Replace(&quot;%20&quot;, &quot; &quot;)
154180
+ Path.GetExtension(encodedFilename);
155181
}
156182
}
157183
</pre>
158-
<hr/>
159-
<pre>
184+
<hr />
185+
<pre>
160186
Some &lt;Pre&gt; starting one
161187
line below! </pre>
162188

163189
</div>
164190

165191
<div style='margin-top: 20px; border: 1px dashed rgba(0, 0, 0, 0.4); background: olive; color: white; display: flex; gap: 5px; padding: 6px 8px; font-size: 14px;'>
166-
<div>
167-
<p>Header placeholder:</p>
168-
<ol>
169-
<li>Item 1</li>
170-
<li>Item 2</li>
171-
</ol>
172-
<p style='text-indent: 4.5em'>Footer Placeholder</p>
173-
</div>
192+
<div>
193+
<p>Header placeholder:</p>
194+
<ol>
195+
<li>Item 1</li>
196+
<li>Item 2</li>
197+
</ol>
198+
<p style='text-indent: 4.5em'>Footer Placeholder</p>
199+
</div>
174200
</div>
175201

176202
<div style="border: 1px dashed salmon; margin: 1em">Lorem Ipsum</div>
177-
<!--<div style="page-break-before: always">
203+
<!--<div style="page-break-before: always">
178204
New page
179205
</div>-->
180206
</body>

src/Html2OpenXml/Collections/HtmlAttributeCollection.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ namespace HtmlToOpenXml;
2020
/// </summary>
2121
sealed class HtmlAttributeCollection
2222
{
23-
private static readonly Regex stripStyleAttributesRegex = new(@"(?<name>.+?):\s*(?<val>[^;]+);*\s*");
24-
23+
private static readonly Regex stripStyleAttributesRegex = new(@"(?<name>[^;\s]+)\s?(&\#58;|:)\s?(?<val>[^;&]+)\s?(;|&\#59;)*");
2524
private readonly Dictionary<string, string> attributes = [];
2625

2726

@@ -37,13 +36,7 @@ public static HtmlAttributeCollection ParseStyle(string? htmlTag)
3736

3837
// Encoded ':' and ';' characters are valid for browser but not handled by the regex (bug #13812 reported by robin391)
3938
// ex= <span style="text-decoration&#58;underline&#59;color:red">
40-
MatchCollection matches = stripStyleAttributesRegex.Matches(
41-
#if NET5_0_OR_GREATER
42-
System.Web.HttpUtility.HtmlDecode(htmlTag)
43-
#else
44-
HttpUtility.HtmlDecode(htmlTag)
45-
#endif
46-
);
39+
MatchCollection matches = stripStyleAttributesRegex.Matches(htmlTag);
4740
foreach (Match m in matches)
4841
collection.attributes[m.Groups["name"].Value] = m.Groups["val"].Value;
4942

src/Html2OpenXml/Expressions/BlockElementExpression.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ protected override void ComposeStyles (ParsingContext context)
168168
};
169169
}
170170

171-
var attrValue = styleAttributes!["text-align"];
172-
JustificationValues? align = Converter.ToParagraphAlign(attrValue);
171+
JustificationValues? align = Converter.ToParagraphAlign(styleAttributes!["text-align"]);
172+
if (!align.HasValue) align = Converter.ToParagraphAlign(node.GetAttribute("align"));
173173
if (align.HasValue)
174174
{
175175
paraProperties.Justification = new() { Val = align };

src/Html2OpenXml/Expressions/HyperlinkExpression.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public override IEnumerable<OpenXmlElement> Interpret (ParsingContext context)
113113
h = new Hyperlink() { History = true, Anchor = "_top" };
114114
}
115115
// is it an anchor?
116-
else if (!context.Converter.ExcludeLinkAnchor && linkNode.Hash.Length > 1 && linkNode.Hash[0] == '#')
116+
else if (context.Converter.SupportsAnchorLinks && linkNode.Hash.Length > 1 && linkNode.Hash[0] == '#')
117117
{
118118
h = new Hyperlink(
119119
) { History = true, Anchor = linkNode.Hash.Substring(1) };

0 commit comments

Comments
 (0)