Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/publish_nuget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This workflow will build, pack and deploy the solution on Nuget

name: 'publish_nuget.yml'

on:
push:
tags:
- '[0-9]+.[0-9]+'
branches:
- master

jobs:
publish:
if: startsWith(github.ref, 'refs/tags/') && github.ref_type == 'tag' && github.ref_name != ''
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Ensure tag is on master
run: |
TAG_COMMIT=$(git rev-list -n 1 ${{ github.ref_name }})
if ! git merge-base --is-ancestor $TAG_COMMIT origin/master; then
echo "Tag is not on master branch. Skipping publish."
exit 1
fi
- name: Setup .NET 8.
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Build
run: dotnet build --configuration Release
- name: Pack
run: dotnet pack src/Html2OpenXml/HtmlToOpenXml.csproj --configuration Release --output ./nupkg
- name: Push nuget to NuGet.org
run: dotnet nuget push ./nupkg/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json
- name: Create Release and Upload Artifact to Release
run: gh release create ${{github.ref_name}} -t "Release ${{github.ref_name}}" *.nupkg --generate-notes --draft
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 3.2.6

- Fix handling Uri with an anchor #209
- New option DefaultStyles.NumberedHeadingStyle to support an alternate heading style #210

## 3.2.5

- Fix a crash with the new whitespace handling introduced in 3.2.3 #191
Expand Down
13 changes: 7 additions & 6 deletions src/Html2OpenXml/Expressions/HyperlinkExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,6 @@ public override IEnumerable<OpenXmlElement> Interpret (ParsingContext context)
{
h = new Hyperlink() { History = true, Anchor = "_top" };
}
// is it an anchor?
else if (context.Converter.SupportsAnchorLinks && linkNode.Hash.Length > 1 && linkNode.Hash[0] == '#')
{
h = new Hyperlink(
) { History = true, Anchor = linkNode.Hash.Substring(1) };
}
// ensure the links does not start with javascript:
else if (AngleSharpExtensions.TryParseUrl(att, UriKind.Absolute, out var uri))
{
Expand All @@ -126,6 +120,13 @@ public override IEnumerable<OpenXmlElement> Interpret (ParsingContext context)
h = new Hyperlink(
) { History = true, Id = extLink.Id };
}
// is it an anchor?
else if (context.Converter.SupportsAnchorLinks && linkNode.Hash.Length > 1 && linkNode.Hash[0] == '#')
{
h = new Hyperlink(
)
{ History = true, Anchor = linkNode.Hash.Substring(1) };
}

if (h == null)
{
Expand Down
45 changes: 31 additions & 14 deletions src/Html2OpenXml/Expressions/Numbering/HeadingElementExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,43 @@ public override IEnumerable<OpenXmlElement> Interpret (ParsingContext context)

paragraph ??= new(childElements);
paragraph.ParagraphProperties ??= new();
paragraph.ParagraphProperties.ParagraphStyleId =
context.DocumentStyle.GetParagraphStyle(context.DocumentStyle.DefaultStyles.HeadingStyle + level);


var runElement = childElements.FirstOrDefault();
if (runElement != null && context.Converter.SupportsHeadingNumbering && IsNumbering(runElement))
{
var abstractNumId = GetOrCreateListTemplate(context, HeadingNumberingName);
var instanceId = GetListInstance(abstractNumId);
if (!instanceId.HasValue)
if (string.Equals(context.DocumentStyle.DefaultStyles.HeadingStyle, context.DocumentStyle.DefaultStyles.NumberedHeadingStyle))
{
instanceId = IncrementInstanceId(context, abstractNumId);
// Only apply the numbering if a custom numbered heading style has not been defined.
// If the user defined a custom numbered heading style (with numbering), Word has
// the numbering automatically done.
// Defining a numbering here messes that up, so we only add the numbering if
// a specific numbering heading style has not been provided
var abstractNumId = GetOrCreateListTemplate(context, HeadingNumberingName);
var instanceId = GetListInstance(abstractNumId);

if (!instanceId.HasValue)
{
instanceId = IncrementInstanceId(context, abstractNumId);
}

var numbering = context.MainPart.NumberingDefinitionsPart!.Numbering!;
numbering.Append(
new NumberingInstance(
new AbstractNumId() { Val = abstractNumId }
)
{ NumberID = instanceId });
SetNumbering(paragraph, level - '0', instanceId.Value);
}

var numbering = context.MainPart.NumberingDefinitionsPart!.Numbering!;
numbering.Append(
new NumberingInstance(
new AbstractNumId() { Val = abstractNumId }
)
{ NumberID = instanceId });
SetNumbering(paragraph, level - '0', instanceId.Value);
// Apply numbered heading style
paragraph.ParagraphProperties.ParagraphStyleId =
context.DocumentStyle.GetParagraphStyle(context.DocumentStyle.DefaultStyles.NumberedHeadingStyle + level);
}
else
{
// Apply normal heading style
paragraph.ParagraphProperties.ParagraphStyleId =
context.DocumentStyle.GetParagraphStyle(context.DocumentStyle.DefaultStyles.HeadingStyle + level);
}

return [paragraph];
Expand Down
4 changes: 2 additions & 2 deletions src/Html2OpenXml/HtmlToOpenXml.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
<AssemblyName>HtmlToOpenXml</AssemblyName>
<RootNamespace>HtmlToOpenXml</RootNamespace>
<PackageId>HtmlToOpenXml.dll</PackageId>
<Version>3.2.5</Version>
<Version>3.2.6</Version>
<PackageIcon>icon.png</PackageIcon>
<Copyright>Copyright 2009-$([System.DateTime]::Now.Year) Olivier Nizet</Copyright>
<PackageReleaseNotes>See changelog https://github.com/onizet/html2openxml/blob/master/CHANGELOG.md</PackageReleaseNotes>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageTags>office openxml netcore html</PackageTags>
<AssemblyVersion>3.2.5</AssemblyVersion>
<AssemblyVersion>3.2.6</AssemblyVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/onizet/html2openxml</PackageProjectUrl>
<RepositoryUrl>https://github.com/onizet/html2openxml</RepositoryUrl>
Expand Down
7 changes: 7 additions & 0 deletions src/Html2OpenXml/Primitives/DefaultStyles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ public class DefaultStyles
/// <value>Heading</value>
public string HeadingStyle { get; set; } = PredefinedStyles.Heading;

/// <summary>
/// Default style for numbered headings
/// Appends the level at the end of the style name
/// </summary>
/// <value>Heading</value>
public string NumberedHeadingStyle { get; set; } = PredefinedStyles.Heading;

/// <summary>
/// Default style for hyperlinks
/// </summary>
Expand Down
12 changes: 7 additions & 5 deletions test/HtmlToOpenXml.Tests/LinkTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ public class LinkTests : HtmlConverterTestBase
[TestCase("://www.site.com")]
[TestCase("www.site.com")]
[TestCase("http://www.site.com")]
public void ExternalLink_ShouldSucceed (string link)
[TestCase("http://www.site.com/#anchor1", "http://www.site.com/#anchor1")]
public void ExternalLink_ShouldSucceed(string link, string expectedUri = "http://www.site.com/")
{
var elements = converter.Parse($@"<a href=""{link}"" title=""Test Tooltip"">Test Caption</a>");
AssertHyperlink(mainPart, elements);
AssertHyperlink(mainPart, elements, expectedUri);
}

[TestCase(@"<a href=""javascript:alert()"">Js</a>")]
Expand Down Expand Up @@ -193,7 +194,7 @@ public async Task ParseIntoDocumentPart_ReturnsHyperlinkParentedToPart (Type ope
throw new NotSupportedException($"Test case not supported for {openXmlPartType.FullName}");
}

AssertHyperlink(container, host.ChildElements);
AssertHyperlink(container, host.ChildElements, "http://www.site.com/");
AssertThatOpenXmlDocumentIsValid();
}

Expand Down Expand Up @@ -249,7 +250,8 @@ await converter.ParseBody(@"<a href='#_top'>Move to top
Assert.That(rel.Uri.ToString(), Is.EqualTo("#_top"));
}

private static void AssertHyperlink(OpenXmlPartContainer container, IEnumerable<OpenXmlElement> elements)
private static void AssertHyperlink(OpenXmlPartContainer container, IEnumerable<OpenXmlElement> elements,
string expectedUri)
{
Assert.That(elements.Count(), Is.EqualTo(1));
Assert.Multiple(() => {
Expand All @@ -272,7 +274,7 @@ private static void AssertHyperlink(OpenXmlPartContainer container, IEnumerable<
var extLink = container.HyperlinkRelationships.FirstOrDefault(r => r.Id == hyperlink.Id);
Assert.That(extLink, Is.Not.Null);
Assert.That(extLink.IsExternal, Is.EqualTo(true));
Assert.That(extLink.Uri.AbsoluteUri, Is.EqualTo("http://www.site.com/"));
Assert.That(extLink.Uri.AbsoluteUri, Is.EqualTo(expectedUri));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public MockHttpMessageHandler(Func<Uri, Task<HttpResponseMessage>> getResponseFu

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await _getResponseFunc(request.RequestUri);
return await _getResponseFunc(request.RequestUri!);
}
}
}
Loading