Skip to content

Commit 1a14761

Browse files
authored
Fix nested lists and allow list style attribute (#198)
Fix nested ordered lists which change type not restarting (e.g. nesting a lower-alpha list in a decimal list would not restart the numbering). Added support for parsing the <ol type="1|a|A|i|I"> attribute.
1 parent 1fd6109 commit 1a14761

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

src/Html2OpenXml/Expressions/Numbering/ListExpression.cs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved
1+
/* Copyright (C) Olivier Nizet https://github.com/onizet/html2openxml - All Rights Reserved
22
*
33
* This source is subject to the Microsoft Permissive License.
44
* Please see the License.txt file for more information.
@@ -161,7 +161,15 @@ private ListContext ConcretiseInstance(ParsingContext context, int abstractNumId
161161
int overrideLevelIndex = 0;
162162
var isOrderedTag = node.NodeName.Equals("ol", StringComparison.OrdinalIgnoreCase);
163163
var dir = node.GetTextDirection();
164-
if (!instanceId.HasValue || context.Converter.ContinueNumbering == false)
164+
165+
// be sure to restart to 1 any nested ordered list
166+
if (currentLevel > 0 && isOrderedTag)
167+
{
168+
instanceId = IncrementInstanceId(context, abstractNumId, isReusable: false);
169+
overrideLevelIndex = currentLevel;
170+
listContext = new ListContext(listStyle, abstractNumId, instanceId.Value, currentLevel + 1, dir);
171+
}
172+
else if (!instanceId.HasValue || context.Converter.ContinueNumbering == false)
165173
{
166174
// create a new instance of that list template
167175
instanceId = IncrementInstanceId(context, abstractNumId, isReusable: context.Converter.ContinueNumbering);
@@ -176,13 +184,6 @@ private ListContext ConcretiseInstance(ParsingContext context, int abstractNumId
176184
instanceId = IncrementInstanceId(context, abstractNumId, isReusable: false);
177185
listContext = new ListContext(listStyle, abstractNumId, instanceId.Value, 1, dir);
178186
}
179-
// be sure to restart to 1 any nested ordered list
180-
else if (currentLevel > 0 && isOrderedTag)
181-
{
182-
instanceId = IncrementInstanceId(context, abstractNumId, isReusable: false);
183-
overrideLevelIndex = currentLevel;
184-
listContext = new ListContext(listStyle, abstractNumId, instanceId.Value, currentLevel + 1, dir);
185-
}
186187
else
187188
{
188189
return new ListContext(listStyle, abstractNumId, instanceId.Value, currentLevel + 1, dir);
@@ -215,20 +216,39 @@ private ListContext ConcretiseInstance(ParsingContext context, int abstractNumId
215216
private static string GetListName(IElement listNode, string? parentName = null)
216217
{
217218
var styleAttributes = listNode.GetStyles();
219+
bool orderedList = listNode.NodeName.Equals("ol", StringComparison.OrdinalIgnoreCase);
218220
string? type = styleAttributes["list-style-type"];
219221

222+
if(orderedList && string.IsNullOrEmpty(type))
223+
{
224+
type = ListTypeToListStyleType(listNode.GetAttribute("type"));
225+
}
226+
220227
if (string.IsNullOrEmpty(type) || !supportedListTypes.Contains(type!))
221228
{
222229
if (parentName != null && IsCascadingStyle(parentName))
223230
return parentName!;
224231

225-
bool orderedList = listNode.NodeName.Equals("ol", StringComparison.OrdinalIgnoreCase);
226232
type = orderedList? "decimal" : "disc";
227233
}
228234

229235
return type!;
230236
}
231237

238+
/// <summary>
239+
/// Map ordered list style attribute values to css list-style-type.
240+
/// Valid types are "1|a|A|i|I": https://w3schools.com/tags/att_ol_type.asp
241+
/// </summary>
242+
private static string? ListTypeToListStyleType(string? type) => type switch
243+
{
244+
"1" => "decimal",
245+
"a" => "lower-alpha",
246+
"A" => "upper-alpha",
247+
"i" => "lower-roman",
248+
"I" => "upper-roman",
249+
_ => null
250+
};
251+
232252
/// <summary>
233253
/// Resolve the <see cref="ParagraphStyleId"/> of a list element node,
234254
/// based on its css class if provided and if matching.
@@ -256,4 +276,4 @@ private static bool IsCascadingStyle(string styleName)
256276
{
257277
return styleName == "decimal-tiered";
258278
}
259-
}
279+
}

0 commit comments

Comments
 (0)