Compare commits

...

42 Commits

Author SHA1 Message Date
Alexandre Mutel
5e3527b7d2 Bump to 0.27.0 2022-01-23 16:10:37 +01:00
Alexandre Mutel
d56e080fd7 Merge pull request #590 from yufeih/bug-crlf-link
Fix link reference definition parse bug with title and CRLF
2022-01-23 16:05:02 +01:00
Yufei Huang
d807255e13 Fix link reference definition parse bug with title and CRLF 2022-01-21 23:37:27 +08:00
Alexandre Mutel
029da6c99b Merge pull request #587 from wbaldoumas/add_markdown_colorcode
Add Markdown.ColorCode to README
2022-01-20 13:29:33 +01:00
Alexandre Mutel
b59c9e8925 Merge pull request #586 from tibel/feature/net6.0
.NET 6.0
2022-01-20 13:29:18 +01:00
Alexandre Mutel
22662b248d Update src/global.json 2022-01-20 12:50:58 +01:00
William Baldoumas
9d51ab176c Add Markdown.ColorCode 2022-01-19 21:37:52 -05:00
Thomas Ibel
584378967d fix build warnings 2022-01-19 20:12:41 +01:00
Thomas Ibel
f553bdd4c7 use await for http client 2022-01-19 19:18:46 +01:00
Thomas Ibel
16d77b7bb8 fix github action version 2022-01-19 18:46:54 +01:00
Thomas Ibel
d267cbe173 update github actions 2022-01-19 18:40:19 +01:00
Thomas Ibel
f54944962f update test and benchmark dependencies 2022-01-19 18:32:17 +01:00
Thomas Ibel
5a54af1235 fix warnings 2022-01-19 18:05:28 +01:00
Thomas Ibel
4567d86c15 use .NET 6.0 SDK 2022-01-19 18:01:30 +01:00
Alexandre Mutel
2b6dde9415 Merge pull request #576 from SimonCropp/patch-1
Strike.V8 is deprecated
2021-11-26 08:11:18 +01:00
Simon Cropp
ea8d9b608a Strike.V8 is deprecated 2021-11-15 13:53:50 +11:00
Alexandre Mutel
1469cc8fdb Merge pull request #575 from boxofyellow/master
Fix typo in EmphasisExtraOptions descriptions
2021-10-31 09:14:13 +01:00
Alexandre Mutel
daf2171366 Update src/Markdig/Extensions/EmphasisExtras/EmphasisExtraOptions.cs
Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
2021-10-31 08:54:20 +01:00
Alexandre Mutel
63a9f2406b Update src/Markdig/Extensions/EmphasisExtras/EmphasisExtraOptions.cs
Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
2021-10-31 08:54:12 +01:00
boxofyellow
fd100d1796 Fix typos in EmphasisExtraOptions descriptions 2021-10-30 14:55:59 -04:00
Alexandre Mutel
2c5a51d89b Merge pull request #572 from flcdrg/patch-1
Fix named parameter syntax
2021-09-16 06:21:45 +02:00
Alexandre Mutel
28db7fbd6b Merge pull request #573 from lajjne/target-blank
Fixes #571
2021-09-16 06:21:14 +02:00
Linus Birgerstam
56470a72a8 Fixes #571 2021-09-15 20:08:17 +02:00
David Gardiner
6b163a50c3 Fix named parameter syntax 2021-09-14 18:40:25 +09:30
Alexandre Mutel
c0ee97a803 Bump to 0.26.0 2021-08-27 20:34:30 +02:00
Alexandre Mutel
63ce549ea2 Merge pull request #570 from Sleepyowl/master
Fixes xoofx/markdig#567
2021-08-27 20:24:45 +02:00
Dmtry Soloviev
0faf0ef430 Make Mathematics extension respect EnableHtml* options 2021-08-24 23:03:02 +02:00
Alexandre Mutel
cdd4b40469 Merge pull request #560 from yufeih/yufeih/fix-crlf
Fix rendering diff between line endings
2021-07-06 18:36:32 +02:00
Yufei Huang
54d85ebac6 Fix rendering diff between line endings 2021-06-29 16:18:42 +08:00
Alexandre Mutel
64875c3dd9 Bump to 0.25.0 2021-06-10 09:02:03 +02:00
Alexandre Mutel
4c92fe5a3b Fix regression when parsing link reference definitions (#543) 2021-06-10 08:58:53 +02:00
Alexandre Mutel
27f625f15b Merge pull request #548 from Mysteryduck001/master
JiraLinkInlineParser.cs - Make digits in JiraKey's posible
2021-05-08 12:01:32 +02:00
Mysteryduck001
aca085703e JiraLinks.Generated.cs - add test for JiraKey's starting with a digit (not allowed) 2021-05-03 17:28:11 +02:00
Mysteryduck001
8aa0948b20 JiraLinkInlineParser.cs - prevent Jira key's to start with a digit 2021-05-03 17:22:13 +02:00
Mysteryduck001
8ce6f4d9ad JiraLinks.md - Do not allow a digit to be the first Char of the Key 2021-05-03 17:18:36 +02:00
Mysteryduck001
3a47a5115a JiraLinks.generated.cs - updated tests for JiraLink 2021-05-03 17:14:25 +02:00
Mysteryduck001
a8737e8481 JiraLinks.md - add examples with JiraKeys using Digits 2021-05-03 17:03:31 +02:00
Mysteryduck001
f56b8e6ba7 JiraLinkInlineParser.cs - Make digits in JiraKey's posible 2021-05-03 16:32:08 +02:00
Alexandre Mutel
0a0040450f Merge pull request #544 from generateui/fix_535
ignore whitespace at end of pipe table row header
2021-04-14 16:38:40 +02:00
Alexandre Mutel
fb12be5ab0 Merge pull request #540 from MihaZupan/coverage-link
Update coverage badge link
2021-04-13 07:35:27 +02:00
Ruud Poutsma
2277596e2e ignore whitespace at end of pipe table row header 2021-04-10 17:59:32 +02:00
MihaZupan
a10f6f6b8c Update coverage badge link 2021-04-07 00:18:57 +02:00
46 changed files with 398 additions and 160 deletions

View File

@@ -18,18 +18,18 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v1
uses: actions/checkout@v2
- name: Install .NET 5.0
- name: Install .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: '5.0.x'
dotnet-version: '6.0.x'
- name: Build (Release)
run: dotnet build src -c Release
- name: SpecFileGen
run: dotnet src/SpecFileGen/bin/Release/net5.0/SpecFileGen.dll
run: dotnet src/SpecFileGen/bin/Release/net6.0/SpecFileGen.dll
- name: Test (Release)
run: dotnet test src -c Release
@@ -38,10 +38,10 @@ jobs:
run: dotnet test src -c Debug
- name: Coverlet
run: dotnet test src -c Release -f net5.0 /p:Include=\"[${{env.PROJECT_NAME}}]*\" /p:CollectCoverage=true /p:CoverletOutputFormat=lcov
run: dotnet test src -c Release -f net6.0 /p:Include=\"[${{env.PROJECT_NAME}}]*\" /p:CollectCoverage=true /p:CoverletOutputFormat=lcov
- name: Coveralls Upload
uses: coverallsapp/github-action@v1.0.1
uses: coverallsapp/github-action@1.1.3
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,5 +1,17 @@
# Changelog
## 0.27.0 (23 Jan 2022)
- Fix link reference definition parse bug with title and CRLF ([PR #590](https://github.com/lunet-io/markdig/pull/590))
- Move tests to net6.0 ([PR #560](https://github.com/lunet-io/markdig/pull/560))
## 0.26.0 (27 Aug 2021)
- Fix rendering diff between line endings ([PR #560](https://github.com/lunet-io/markdig/pull/560))
- Make Mathematics extension respect EnableHtml* options ([PR #570](https://github.com/lunet-io/markdig/pull/570))
## 0.25.0 (10 June 2021)
- Fix regression when parsing link reference definitions (#543)
- Make digits in JiraKey's posible ([PR #548](https://github.com/lunet-io/markdig/pull/548))
## 0.24.0 (20 Mar 2021)
- Add support for roundtrip Markdown ([PR #481](https://github.com/lunet-io/markdig/pull/481))
- Introduction of nullability ([PR #522](https://github.com/lunet-io/markdig/pull/522) [PR #524](https://github.com/lunet-io/markdig/pull/524) [PR #525](https://github.com/lunet-io/markdig/pull/525) [PR #526](https://github.com/lunet-io/markdig/pull/526) [PR #527](https://github.com/lunet-io/markdig/pull/527))

View File

@@ -1,4 +1,4 @@
# Markdig [![Build Status](https://github.com/lunet-io/markdig/workflows/ci/badge.svg?branch=master)](https://github.com/lunet-io/markdig/actions) [![Coverage Status](https://coveralls.io/repos/github/lunet-io/markdig/badge.svg?branch=master)](https://coveralls.io/github/lunet-io/markdig?branch=master) [![NuGet](https://img.shields.io/nuget/v/Markdig.svg)](https://www.nuget.org/packages/Markdig/) [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FRGHXBTP442JL)
# Markdig [![Build Status](https://github.com/lunet-io/markdig/workflows/ci/badge.svg?branch=master)](https://github.com/lunet-io/markdig/actions) [![Coverage Status](https://coveralls.io/repos/github/xoofx/markdig/badge.svg?branch=master)](https://coveralls.io/github/xoofx/markdig?branch=master) [![NuGet](https://img.shields.io/nuget/v/Markdig.svg)](https://www.nuget.org/packages/Markdig/) [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FRGHXBTP442JL)
<img align="right" width="160px" height="160px" src="img/markdig.png">
@@ -60,6 +60,7 @@ If you are looking for support for an old .NET Framework 3.5 or 4.0, you can dow
- [**WPF/XAML Markdown Renderer**: `markdig.wpf`](https://github.com/Kryptos-FR/markdig.wpf)
- [**WPF/XAML Markdown Renderer**: `Neo.Markdig.Xaml`](https://github.com/neolithos/NeoMarkdigXaml)
- [**Syntax highlighting**: `Markdig.SyntaxHighlighting`](https://github.com/RichardSlater/Markdig.SyntaxHighlighting)
- [**Syntax highlighting using ColorCode-Universal**: `Markdown.ColorCode`](https://github.com/wbaldoumas/markdown-colorcode)
- [**Syntax highlighting using Prism.js**: `WebStoating.Markdig.Prism`](https://github.com/ilich/Markdig.Prism)
- [**Embedded C# scripting**: `Markdig.Extensions.ScriptCs`](https://github.com/macaba/Markdig.Extensions.ScriptCs)
@@ -128,10 +129,6 @@ This is an early preview of the benchmarking against various implementations:
- [Marked.NET](https://github.com/T-Alex/MarkedNet) (version: 1.0.5) port of original [marked.js](https://github.com/chjj/marked) project
- [Microsoft.DocAsCode.MarkdownLite](https://github.com/dotnet/docfx/tree/dev/src/Microsoft.DocAsCode.MarkdownLite) (version: 2.0.1) used by the [docfx](https://github.com/dotnet/docfx) project
**JavaScript/V8 implementations**:
- [Strike.V8](https://github.com/SimonCropp/Strike) (version: 1.5.0) [marked.js](https://github.com/chjj/marked) running in Google V8 (not .NET based)
### Analysis of the results:
- Markdig is roughly **x100 times faster than MarkdownSharp**, **30x times faster than docfx**
@@ -166,7 +163,6 @@ CommonMark.NET(pipe_tables) | 5.6164 ms | 0.0298 ms | 0.72 | 111.00| 56.00|
MarkdownDeep | 7.8193 ms | 0.0334 ms | 1.00 | 120.00| 56.00| 49.00| 1,884,854.85 |
cmark | 4.2698 ms | 0.1526 ms | 0.55 | -| -| -| NA |
Moonshine | 6.0929 ms | 0.1053 ms | 1.28 | -| -| -| NA |
Strike.V8 | 10.5895 ms | 0.0492 ms | 1.35 | -| -| -| NA |
Marked.NET | 207.3169 ms | 5.2628 ms | 26.51 | 0.00| 0.00| 0.00| 303,125,228.65 |
MarkdownSharp | 675.0185 ms | 2.8447 ms | 86.32 | 40.00| 27.00| 41.00| 2,413,394.17 |
Microsoft DocfxMarkdownLite | 166.3357 ms | 0.4529 ms | 21.27 |4,452.00|948.00|11,167.00| 180,218,359.60 |

View File

@@ -36,12 +36,12 @@
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.1" />
<PackageReference Include="CommonMark.NET" Version="0.15.1" />
<PackageReference Include="MarkdownSharp" Version="2.0.5" />
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.0.161401" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.62" />
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.0.226801" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.74" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Markdig\Markdig.csproj" />

View File

@@ -1,20 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<StartupObject>Markdig.Tests.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="2.9.0">
<PackageReference Include="coverlet.msbuild" Version="3.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -272,7 +272,7 @@ $$
var newWindowPipeline = new MarkdownPipelineBuilder().UseAutoLinks(new AutoLinkOptions() { OpenInNewWindow = true }).Build();
TestParser.TestSpec("www.foo.bar", "<p><a href=\"http://www.foo.bar\">www.foo.bar</a></p>", pipeline);
TestParser.TestSpec("www.foo.bar", "<p><a href=\"http://www.foo.bar\" target=\"blank\">www.foo.bar</a></p>", newWindowPipeline);
TestParser.TestSpec("www.foo.bar", "<p><a href=\"http://www.foo.bar\" target=\"_blank\">www.foo.bar</a></p>", newWindowPipeline);
}
[Test]

View File

@@ -115,9 +115,9 @@ namespace Markdig.Tests.RoundtripSpecs
}
//[TestCase("\n")]
//[TestCase("\r\n")]
//[TestCase("\r")]
[TestCase("\n")]
[TestCase("\r\n")]
[TestCase("\r")]
[TestCase("p\n")]
[TestCase("p\r")]

View File

@@ -23,7 +23,7 @@ namespace Markdig.Tests.Specs.JiraLinks
//
// The rules for detecting a link are:
//
// - The project key must be composed of one or more capitalized ASCII letter `[A-Z]+`
// - The project key must be composed of one or more capitalized ASCII letters or digits `[A-Z,0-9]+`
// - A single hyphen `-` must separate the project key and issue number.
// - The issue number is composed of 1 or more digits `[0, 9]+`
// - The reference must be preceded by either `(` or whitespace or EOF.
@@ -40,10 +40,10 @@ namespace Markdig.Tests.Specs.JiraLinks
// This is a ABCD-123 issue
//
// Should be rendered as:
// <p>This is a <a href="http://your.company.abc/browse/ABCD-123" target="blank">ABCD-123</a> issue</p>
// <p>This is a <a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a> issue</p>
Console.WriteLine("Example 1\nSection Jira Links\n");
TestParser.TestSpec("This is a ABCD-123 issue", "<p>This is a <a href=\"http://your.company.abc/browse/ABCD-123\" target=\"blank\">ABCD-123</a> issue</p>", "jiralinks");
TestParser.TestSpec("This is a ABCD-123 issue", "<p>This is a <a href=\"http://your.company.abc/browse/ABCD-123\" target=\"_blank\">ABCD-123</a> issue</p>", "jiralinks");
}
[Test]
@@ -53,13 +53,13 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is a KIRA-1 issue
// This is a ABC4-123 issue
//
// Should be rendered as:
// <p>This is a <a href="http://your.company.abc/browse/KIRA-1" target="blank">KIRA-1</a> issue</p>
// <p>This is a <a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a> issue</p>
Console.WriteLine("Example 2\nSection Jira Links\n");
TestParser.TestSpec("This is a KIRA-1 issue", "<p>This is a <a href=\"http://your.company.abc/browse/KIRA-1\" target=\"blank\">KIRA-1</a> issue</p>", "jiralinks");
TestParser.TestSpec("This is a ABC4-123 issue", "<p>This is a <a href=\"http://your.company.abc/browse/ABC4-123\" target=\"_blank\">ABC4-123</a> issue</p>", "jiralinks");
}
[Test]
@@ -69,16 +69,15 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is a Z-1 issue
// This is a ABC45-123 issue
//
// Should be rendered as:
// <p>This is a <a href="http://your.company.abc/browse/Z-1" target="blank">Z-1</a> issue</p>
// <p>This is a <a href="http://your.company.abc/browse/ABC45-123" target="_blank">ABC45-123</a> issue</p>
Console.WriteLine("Example 3\nSection Jira Links\n");
TestParser.TestSpec("This is a Z-1 issue", "<p>This is a <a href=\"http://your.company.abc/browse/Z-1\" target=\"blank\">Z-1</a> issue</p>", "jiralinks");
TestParser.TestSpec("This is a ABC45-123 issue", "<p>This is a <a href=\"http://your.company.abc/browse/ABC45-123\" target=\"_blank\">ABC45-123</a> issue</p>", "jiralinks");
}
// These are also valid links with `(` and `)`:
[Test]
public void JiraLinks_Example004()
{
@@ -86,13 +85,13 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is a (ABCD-123) issue
// This is a KIRA-1 issue
//
// Should be rendered as:
// <p>This is a (<a href="http://your.company.abc/browse/ABCD-123" target="blank">ABCD-123</a>) issue</p>
// <p>This is a <a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a> issue</p>
Console.WriteLine("Example 4\nSection Jira Links\n");
TestParser.TestSpec("This is a (ABCD-123) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/ABCD-123\" target=\"blank\">ABCD-123</a>) issue</p>", "jiralinks");
TestParser.TestSpec("This is a KIRA-1 issue", "<p>This is a <a href=\"http://your.company.abc/browse/KIRA-1\" target=\"_blank\">KIRA-1</a> issue</p>", "jiralinks");
}
[Test]
@@ -102,15 +101,16 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is a (KIRA-1) issue
// This is a Z-1 issue
//
// Should be rendered as:
// <p>This is a (<a href="http://your.company.abc/browse/KIRA-1" target="blank">KIRA-1</a>) issue</p>
// <p>This is a <a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a> issue</p>
Console.WriteLine("Example 5\nSection Jira Links\n");
TestParser.TestSpec("This is a (KIRA-1) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/KIRA-1\" target=\"blank\">KIRA-1</a>) issue</p>", "jiralinks");
TestParser.TestSpec("This is a Z-1 issue", "<p>This is a <a href=\"http://your.company.abc/browse/Z-1\" target=\"_blank\">Z-1</a> issue</p>", "jiralinks");
}
// These are also valid links with `(` and `)`:
[Test]
public void JiraLinks_Example006()
{
@@ -118,16 +118,15 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is a (Z-1) issue
// This is a (ABCD-123) issue
//
// Should be rendered as:
// <p>This is a (<a href="http://your.company.abc/browse/Z-1" target="blank">Z-1</a>) issue</p>
// <p>This is a (<a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a>) issue</p>
Console.WriteLine("Example 6\nSection Jira Links\n");
TestParser.TestSpec("This is a (Z-1) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/Z-1\" target=\"blank\">Z-1</a>) issue</p>", "jiralinks");
TestParser.TestSpec("This is a (ABCD-123) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/ABCD-123\" target=\"_blank\">ABCD-123</a>) issue</p>", "jiralinks");
}
// These are not valid links:
[Test]
public void JiraLinks_Example007()
{
@@ -135,13 +134,13 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is not aJIRA-123 issue
// This is a (ABC4-123) issue
//
// Should be rendered as:
// <p>This is not aJIRA-123 issue</p>
// <p>This is a (<a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a>) issue</p>
Console.WriteLine("Example 7\nSection Jira Links\n");
TestParser.TestSpec("This is not aJIRA-123 issue", "<p>This is not aJIRA-123 issue</p>", "jiralinks");
TestParser.TestSpec("This is a (ABC4-123) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/ABC4-123\" target=\"_blank\">ABC4-123</a>) issue</p>", "jiralinks");
}
[Test]
@@ -151,13 +150,13 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is not JIRA-123a issue
// This is a (KIRA-1) issue
//
// Should be rendered as:
// <p>This is not JIRA-123a issue</p>
// <p>This is a (<a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a>) issue</p>
Console.WriteLine("Example 8\nSection Jira Links\n");
TestParser.TestSpec("This is not JIRA-123a issue", "<p>This is not JIRA-123a issue</p>", "jiralinks");
TestParser.TestSpec("This is a (KIRA-1) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/KIRA-1\" target=\"_blank\">KIRA-1</a>) issue</p>", "jiralinks");
}
[Test]
@@ -167,13 +166,94 @@ namespace Markdig.Tests.Specs.JiraLinks
// Section: Jira Links
//
// The following Markdown:
// This is a (Z-1) issue
//
// Should be rendered as:
// <p>This is a (<a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a>) issue</p>
Console.WriteLine("Example 9\nSection Jira Links\n");
TestParser.TestSpec("This is a (Z-1) issue", "<p>This is a (<a href=\"http://your.company.abc/browse/Z-1\" target=\"_blank\">Z-1</a>) issue</p>", "jiralinks");
}
// These are not valid links:
[Test]
public void JiraLinks_Example010()
{
// Example 10
// Section: Jira Links
//
// The following Markdown:
// This is not aJIRA-123 issue
//
// Should be rendered as:
// <p>This is not aJIRA-123 issue</p>
Console.WriteLine("Example 10\nSection Jira Links\n");
TestParser.TestSpec("This is not aJIRA-123 issue", "<p>This is not aJIRA-123 issue</p>", "jiralinks");
}
[Test]
public void JiraLinks_Example011()
{
// Example 11
// Section: Jira Links
//
// The following Markdown:
// This is not 4JIRA-123 issue
//
// Should be rendered as:
// <p>This is not 4JIRA-123 issue</p>
Console.WriteLine("Example 11\nSection Jira Links\n");
TestParser.TestSpec("This is not 4JIRA-123 issue", "<p>This is not 4JIRA-123 issue</p>", "jiralinks");
}
[Test]
public void JiraLinks_Example012()
{
// Example 12
// Section: Jira Links
//
// The following Markdown:
// This is not JIRA-123a issue
//
// Should be rendered as:
// <p>This is not JIRA-123a issue</p>
Console.WriteLine("Example 12\nSection Jira Links\n");
TestParser.TestSpec("This is not JIRA-123a issue", "<p>This is not JIRA-123a issue</p>", "jiralinks");
}
[Test]
public void JiraLinks_Example013()
{
// Example 13
// Section: Jira Links
//
// The following Markdown:
// This is not JIRA- issue
//
// Should be rendered as:
// <p>This is not JIRA- issue</p>
Console.WriteLine("Example 9\nSection Jira Links\n");
Console.WriteLine("Example 13\nSection Jira Links\n");
TestParser.TestSpec("This is not JIRA- issue", "<p>This is not JIRA- issue</p>", "jiralinks");
}
[Test]
public void JiraLinks_Example014()
{
// Example 14
// Section: Jira Links
//
// The following Markdown:
// This is not JIR4- issue
//
// Should be rendered as:
// <p>This is not JIR4- issue</p>
Console.WriteLine("Example 14\nSection Jira Links\n");
TestParser.TestSpec("This is not JIR4- issue", "<p>This is not JIR4- issue</p>", "jiralinks");
}
}
}

View File

@@ -10,7 +10,7 @@ var pipeline = new MarkdownPipelineBuilder()
The rules for detecting a link are:
- The project key must be composed of one or more capitalized ASCII letter `[A-Z]+`
- The project key must be composed of one or more capitalized ASCII letters or digits `[A-Z,0-9]+`
- A single hyphen `-` must separate the project key and issue number.
- The issue number is composed of 1 or more digits `[0, 9]+`
- The reference must be preceded by either `(` or whitespace or EOF.
@@ -21,19 +21,31 @@ The following are valid examples:
```````````````````````````````` example
This is a ABCD-123 issue
.
<p>This is a <a href="http://your.company.abc/browse/ABCD-123" target="blank">ABCD-123</a> issue</p>
<p>This is a <a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a> issue</p>
````````````````````````````````
```````````````````````````````` example
This is a ABC4-123 issue
.
<p>This is a <a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a> issue</p>
````````````````````````````````
```````````````````````````````` example
This is a ABC45-123 issue
.
<p>This is a <a href="http://your.company.abc/browse/ABC45-123" target="_blank">ABC45-123</a> issue</p>
````````````````````````````````
```````````````````````````````` example
This is a KIRA-1 issue
.
<p>This is a <a href="http://your.company.abc/browse/KIRA-1" target="blank">KIRA-1</a> issue</p>
<p>This is a <a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a> issue</p>
````````````````````````````````
```````````````````````````````` example
This is a Z-1 issue
.
<p>This is a <a href="http://your.company.abc/browse/Z-1" target="blank">Z-1</a> issue</p>
<p>This is a <a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a> issue</p>
````````````````````````````````
These are also valid links with `(` and `)`:
@@ -41,19 +53,25 @@ These are also valid links with `(` and `)`:
```````````````````````````````` example
This is a (ABCD-123) issue
.
<p>This is a (<a href="http://your.company.abc/browse/ABCD-123" target="blank">ABCD-123</a>) issue</p>
<p>This is a (<a href="http://your.company.abc/browse/ABCD-123" target="_blank">ABCD-123</a>) issue</p>
````````````````````````````````
```````````````````````````````` example
This is a (ABC4-123) issue
.
<p>This is a (<a href="http://your.company.abc/browse/ABC4-123" target="_blank">ABC4-123</a>) issue</p>
````````````````````````````````
```````````````````````````````` example
This is a (KIRA-1) issue
.
<p>This is a (<a href="http://your.company.abc/browse/KIRA-1" target="blank">KIRA-1</a>) issue</p>
<p>This is a (<a href="http://your.company.abc/browse/KIRA-1" target="_blank">KIRA-1</a>) issue</p>
````````````````````````````````
```````````````````````````````` example
This is a (Z-1) issue
.
<p>This is a (<a href="http://your.company.abc/browse/Z-1" target="blank">Z-1</a>) issue</p>
<p>This is a (<a href="http://your.company.abc/browse/Z-1" target="_blank">Z-1</a>) issue</p>
````````````````````````````````
These are not valid links:
@@ -64,6 +82,12 @@ This is not aJIRA-123 issue
<p>This is not aJIRA-123 issue</p>
````````````````````````````````
```````````````````````````````` example
This is not 4JIRA-123 issue
.
<p>This is not 4JIRA-123 issue</p>
````````````````````````````````
```````````````````````````````` example
This is not JIRA-123a issue
.
@@ -75,3 +99,9 @@ This is not JIRA- issue
.
<p>This is not JIRA- issue</p>
````````````````````````````````
```````````````````````````````` example
This is not JIR4- issue
.
<p>This is not JIR4- issue</p>
````````````````````````````````

View File

@@ -0,0 +1,17 @@
using NUnit.Framework;
namespace Markdig.Tests
{
[TestFixture]
public class TestNewLine
{
[TestCase("a \nb", "<p>a<br />\nb</p>\n")]
[TestCase("a\\\nb", "<p>a<br />\nb</p>\n")]
[TestCase("a `b\nc`", "<p>a <code>b c</code></p>\n")]
public void Test(string value, string expectedHtml)
{
Assert.AreEqual(expectedHtml, Markdown.ToHtml(value));
Assert.AreEqual(expectedHtml, Markdown.ToHtml(value.Replace("\n", "\r\n")));
}
}
}

View File

@@ -0,0 +1,26 @@
using Markdig.Extensions.Tables;
using Markdig.Syntax;
using NUnit.Framework;
using System.Linq;
namespace Markdig.Tests
{
[TestFixture]
public sealed class TestPipeTable
{
[TestCase("| S | T |\r\n|---|---| \r\n| G | H |")]
[TestCase("| S | T |\r\n|---|---|\t\r\n| G | H |")]
[TestCase("| S | T |\r\n|---|---|\v\r\n| G | H |")]
[TestCase("| S | T |\r\n|---|---|\f\r\n| G | H |")]
[TestCase("| S | T |\r\n|---|---|\f\v\t \r\n| G | H |")]
[TestCase("| S | \r\n|---|\r\n| G |\r\n\r\n| D | D |\r\n| ---| ---| \r\n| V | V |", 2)]
public void TestTableBug(string markdown, int tableCount = 1)
{
MarkdownDocument document = Markdown.Parse(markdown, new MarkdownPipelineBuilder().UseAdvancedExtensions().Build());
Table[] tables = document.Descendants().OfType<Table>().ToArray();
Assert.AreEqual(tableCount, tables.Length);
}
}
}

View File

@@ -12,6 +12,22 @@ namespace Markdig.Tests
[TestFixture]
public class TestPlayParser
{
[Test]
public void TestLinksWithCarriageReturn()
{
var text = "[Link 1][link-1], [link 2][link-2].\r\n\r\n[link-1]: https://example.com\r\n[link-2]: https://example.com";
var result = Markdown.ToHtml(text).TrimEnd();
Assert.AreEqual("<p><a href=\"https://example.com\">Link 1</a>, <a href=\"https://example.com\">link 2</a>.</p>", result);
}
[Test]
public void TestLinksWithTitleAndCarriageReturn()
{
var text = "[Link 1][link-1], [link 2][link-2].\r\n\r\n[link-1]: https://example.com \"title 1\" \r\n[link-2]: https://example.com \"title 2\"";
var result = Markdown.ToHtml(text).TrimEnd();
Assert.AreEqual("<p><a href=\"https://example.com\" title=\"title 1\">Link 1</a>, <a href=\"https://example.com\" title=\"title 2\">link 2</a>.</p>", result);
}
[Test]
public void TestLink()
{

View File

@@ -23,7 +23,8 @@ namespace Markdig.Tests
nr.Write(markdownDocument);
Assert.AreEqual(markdown, sw.ToString());
var result = sw.ToString();
Assert.AreEqual(markdown, result);
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>Markdig.WebApp</AssemblyName>
<OutputType>Exe</OutputType>
@@ -13,7 +13,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.16.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.20.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -2,13 +2,14 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Markdig.WebApp
{
public class Startup
{
public Startup(IHostingEnvironment env)
public Startup(IWebHostEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
@@ -37,7 +38,7 @@ namespace Markdig.WebApp
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{

View File

@@ -201,7 +201,7 @@ namespace Markdig.Extensions.AutoLinks
if (Options.OpenInNewWindow)
{
inline.GetAttributes().AddPropertyIfNotExist("target", "blank");
inline.GetAttributes().AddPropertyIfNotExist("target", "_blank");
}
return true;

View File

@@ -33,12 +33,12 @@ namespace Markdig.Extensions.EmphasisExtras
Superscript = 4,
/// <summary>
/// A text that can be rendered as a inserted using the character ++
/// A text that can be rendered as inserted using the double character ++
/// </summary>
Inserted = 8,
/// <summary>
/// A text that can be rendered as a inserted using the character ==
/// A text that can be rendered as marked using the double character ==
/// </summary>
Marked = 16,
}

View File

@@ -40,8 +40,14 @@ namespace Markdig.Extensions.JiraLinks
var startKey = slice.Start;
var endKey = slice.Start;
//read as many uppercase characters as required - project key
while (current.IsAlphaUpper())
// the first character of the key can not be a digit.
if (current.IsDigit())
{
return false;
}
// read as many uppercase characters or digits as required - project key
while (current.IsAlphaUpper() || current.IsDigit())
{
endKey = slice.Start;
current = slice.NextChar();
@@ -100,7 +106,7 @@ namespace Markdig.Extensions.JiraLinks
if (_options.OpenInNewWindow)
{
jiraLink.GetAttributes().AddProperty("target", "blank");
jiraLink.GetAttributes().AddProperty("target", "_blank");
}
processor.Inline = jiraLink;

View File

@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Markdig.Renderers;
@@ -16,11 +16,19 @@ namespace Markdig.Extensions.Mathematics
protected override void Write(HtmlRenderer renderer, MathBlock obj)
{
renderer.EnsureLine();
renderer.Write("<div").WriteAttributes(obj).WriteLine(">");
renderer.WriteLine("\\[");
renderer.WriteLeafRawLines(obj, true, true);
renderer.Write("\\]");
renderer.WriteLine("</div>");
if (renderer.EnableHtmlForBlock)
{
renderer.Write("<div").WriteAttributes(obj).WriteLine(">");
renderer.WriteLine("\\[");
}
renderer.WriteLeafRawLines(obj, true, renderer.EnableHtmlEscape);
if (renderer.EnableHtmlForBlock)
{
renderer.Write("\\]");
renderer.WriteLine("</div>");
}
}
}
}

View File

@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Markdig.Renderers;
@@ -15,9 +15,24 @@ namespace Markdig.Extensions.Mathematics
{
protected override void Write(HtmlRenderer renderer, MathInline obj)
{
renderer.Write("<span").WriteAttributes(obj).Write(">\\(");
renderer.WriteEscape(ref obj.Content);
renderer.Write("\\)</span>");
if (renderer.EnableHtmlForInline)
{
renderer.Write("<span").WriteAttributes(obj).Write(">\\(");
}
if (renderer.EnableHtmlEscape)
{
renderer.WriteEscape(ref obj.Content);
}
else
{
renderer.Write(ref obj.Content);
}
if (renderer.EnableHtmlForInline)
{
renderer.Write("\\)</span>");
}
}
}
}

View File

@@ -511,13 +511,15 @@ namespace Markdig.Extensions.Tables
// Check the left side of a `|` delimiter
TableColumnAlign? align = null;
if (delimiter.PreviousSibling != null && !ParseHeaderString(delimiter.PreviousSibling, out align))
if (delimiter.PreviousSibling != null &&
!(delimiter.PreviousSibling is LiteralInline li && li.Content.IsEmptyOrWhitespace()) && // ignore parsed whitespace
!ParseHeaderString(delimiter.PreviousSibling, out align))
{
break;
}
// Create aligns until we may have a header row
aligns ??= new List<TableColumnDefinition>();
aligns.Add(new TableColumnDefinition() { Alignment = align });

View File

@@ -159,7 +159,7 @@ namespace Markdig.Helpers
for (int i = start; i <= end; i++)
{
char c = Unsafe.Add(ref textRef, i);
if (c < 128 ? isOpeningCharacter[c] : nonAsciiMap.ContainsKey(c))
if (c < 128 ? isOpeningCharacter[c] : nonAsciiMap!.ContainsKey(c))
{
return i;
}

View File

@@ -606,7 +606,7 @@ namespace Markdig.Helpers
hasOnlyWhiteSpacesSinceLastLine = 1;
}
}
else if (c != '\n' && c != '\r' && (c != '\r' && text.PeekChar() != '\n'))
else if (c != '\n' && c != '\r' && text.PeekChar() != '\n')
{
hasOnlyWhiteSpacesSinceLastLine = 0;
}
@@ -700,7 +700,7 @@ namespace Markdig.Helpers
hasOnlyWhiteSpacesSinceLastLine = 1;
}
}
else if (c != '\n' && c != '\r' && (c != '\r' && text.PeekChar() != '\n'))
else if (c != '\n' && c != '\r' && text.PeekChar() != '\n')
{
hasOnlyWhiteSpacesSinceLastLine = 0;
}
@@ -1141,7 +1141,7 @@ namespace Markdig.Helpers
c = text.NextChar();
}
if (c != '\0' && c != '\n')
if (c != '\0' && c != '\n' && c != '\r' && text.PeekChar() != '\n')
{
// If we were able to parse the url but the title doesn't end with space,
// we are still returning a valid definition
@@ -1158,6 +1158,11 @@ namespace Markdig.Helpers
return false;
}
if (c == '\r' && text.PeekChar() == '\n')
{
text.SkipChar();
}
return true;
}
@@ -1231,7 +1236,9 @@ namespace Markdig.Helpers
var saved = text;
var hasWhiteSpaces = CharIteratorHelper.TrimStartAndCountNewLines(ref text, out int newLineCount, out newLine);
triviaBeforeTitle = new SourceSpan(triviaBeforeTitleStart, text.Start - 1);
// Remove the newline from the trivia (as it may have multiple lines)
var triviaBeforeTitleEnd = text.Start - 1;
triviaBeforeTitle = new SourceSpan(triviaBeforeTitleStart, triviaBeforeTitleEnd);
var c = text.CurrentChar;
if (c == '\'' || c == '"' || c == '(')
{
@@ -1246,6 +1253,9 @@ namespace Markdig.Helpers
{
return false;
}
// Discard the newline if we have a title
newLine = NewLine.None;
}
else
{
@@ -1256,6 +1266,8 @@ namespace Markdig.Helpers
{
if (text.IsEmpty || newLineCount > 0)
{
// If we have an end of line, we need to remove it from the trivia
triviaBeforeTitle.End -= newLine.Length();
triviaAfterTitle = new SourceSpan(text.Start, text.Start - 1);
return true;
}
@@ -1269,7 +1281,7 @@ namespace Markdig.Helpers
c = text.NextChar();
}
if (c != '\0' && c != '\n' && c != '\r' && (c != '\r' && text.PeekChar() != '\n'))
if (c != '\0' && c != '\n' && c != '\r' && text.PeekChar() != '\n')
{
// If we were able to parse the url but the title doesn't end with space,
// we are still returning a valid definition
@@ -1277,6 +1289,7 @@ namespace Markdig.Helpers
{
text = saved;
title = null;
newLine = NewLine.None;
unescapedTitle = SourceSpan.Empty;
triviaAfterTitle = SourceSpan.Empty;
return true;
@@ -1299,6 +1312,7 @@ namespace Markdig.Helpers
else if (c == '\r' && text.PeekChar() == '\n')
{
newLine = NewLine.CarriageReturnLineFeed;
text.SkipChar();
}
else if (c == '\r')
{

View File

@@ -26,6 +26,7 @@ namespace Markdig.Helpers
/// <param name="line">The line.</param>
/// <param name="column">The column.</param>
/// <param name="position">The position.</param>
/// <param name="newLine">The line separation.</param>
public StringLine(StringSlice slice, int line, int column, int position, NewLine newLine)
{
Slice = slice;
@@ -42,6 +43,7 @@ namespace Markdig.Helpers
/// <param name="line">The line.</param>
/// <param name="column">The column.</param>
/// <param name="position">The position.</param>
/// <param name="newLine">The line separation.</param>
public StringLine(ref StringSlice slice, int line, int column, int position, NewLine newLine)
{
Slice = slice;

View File

@@ -299,7 +299,7 @@ namespace Markdig.Helpers
CurrentChar = '\r';
}
}
else if (_offset + 1 == slice.Length)
else if (_offset - 1 == slice.Length)
{
if (newLine == NewLine.CarriageReturnLineFeed)
{

View File

@@ -36,6 +36,7 @@ namespace Markdig.Helpers
/// Initializes a new instance of the <see cref="StringSlice"/> struct.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="newLine">The line separation.</param>
public StringSlice(string text, NewLine newLine)
{
Text = text;
@@ -68,6 +69,7 @@ namespace Markdig.Helpers
/// <param name="text">The text.</param>
/// <param name="start">The start.</param>
/// <param name="end">The end.</param>
/// <param name="newLine">The line separation.</param>
/// <exception cref="ArgumentNullException"></exception>
public StringSlice(string text, int start, int end, NewLine newLine)
{

View File

@@ -4,19 +4,23 @@
<Description>A fast, powerful, CommonMark compliant, extensible Markdown processor for .NET with 20+ builtin extensions (pipetables, footnotes, definition lists... etc.)</Description>
<Copyright>Alexandre Mutel</Copyright>
<NeutralLanguage>en-US</NeutralLanguage>
<VersionPrefix>0.24.0</VersionPrefix>
<VersionPrefix>0.27.0</VersionPrefix>
<Authors>Alexandre Mutel</Authors>
<!-- Markdig.Wpf still supports net452, a target still supported by by Microsoft until January 10, 2023 -->
<!-- see: https://github.com/xoofx/markdig/pull/466 -->
<TargetFrameworks>net452;netstandard2.0;netstandard2.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<PackageTags>Markdown CommonMark md html md2html</PackageTags>
<PackageReleaseNotes>https://github.com/lunet-io/markdig/blob/master/changelog.md</PackageReleaseNotes>
<PackageLicenseExpression>BSD-2-Clause</PackageLicenseExpression>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<PackageIcon>markdig.png</PackageIcon>
<PackageProjectUrl>https://github.com/lunet-io/markdig</PackageProjectUrl>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>9</LangVersion>
<Nullable>enable</Nullable>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!--Add support for sourcelink-->
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
@@ -43,14 +47,10 @@
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="../../img/markdig.png" Pack="true" PackagePath="" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.*" PrivateAssets="All"/>
<None Include="../../readme.md" Pack="true" PackagePath="/"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.*" PrivateAssets="All"/>
</ItemGroup>
</Project>

View File

@@ -83,7 +83,7 @@ namespace Markdig
public bool TrackTrivia { get; internal set; }
/// <summary>
/// Occurs when a document has been processed after the <see cref="MarkdownParser.Parse()"/> method.
/// Occurs when a document has been processed after the <see cref="MarkdownParser.Parse"/> method.
/// </summary>
public event ProcessDocumentDelegate? DocumentProcessed;

View File

@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Markdig.Helpers;
@@ -63,6 +63,12 @@ namespace Markdig.Parsers.Inlines
{
c = ' ';
}
else if (c == '\r')
{
slice.SkipChar();
c = slice.CurrentChar;
continue;
}
if (c == match)
{

View File

@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using Markdig.Helpers;
@@ -66,7 +66,7 @@ namespace Markdig.Parsers.Inlines
}
else
{
if (c == '\n')
if (c == '\n' || c == '\r')
{
processor.Inline = new LineBreakInline()
{

View File

@@ -52,7 +52,8 @@ namespace Markdig.Parsers.Inlines
length = nextStart - slice.Start;
if (!processor.TrackTrivia)
{
if (text[nextStart] == '\n')
var nextText = text[nextStart];
if (nextText == '\n' || nextText == '\r')
{
int end = nextStart - 1;
while (length > 0 && text[end].IsSpace())

View File

@@ -25,12 +25,15 @@ namespace Markdig.Renderers.Html.Inlines
}
set
{
string rel = "nofollow";
if (value && !Rel.Contains(rel))
const string rel = "nofollow";
if (value)
{
Rel = string.IsNullOrEmpty(Rel) ? rel : Rel + $" {rel}";
if (string.IsNullOrEmpty(Rel))
Rel = rel;
else if (!Rel!.Contains(rel))
Rel += $" {rel}";
}
else if (!value && Rel.Contains(rel))
else if (!value && Rel is not null)
{
Rel = Rel.Replace(rel, string.Empty);
}

View File

@@ -5,7 +5,7 @@ Without tracking trivia characters, the renderer must make all kinds of assumpti
To use this functionality, set the optional `trackTrivia` parameter to true when using the static `Markdown` class:
```csharp
MarkdownDocument markdownDocument = Markdown.Parse(inputMarkdown, trackTrivia = true);
MarkdownDocument markdownDocument = Markdown.Parse(inputMarkdown, trackTrivia: true);
```
You will get a parse tree where `Block` and `Inline` instances now have various `Trivia*` properties.
@@ -181,4 +181,4 @@ To support rountrip parsing for documents that contain input characters - but th
# Extensions
Extensions are currently not supported. If you're a writer or maintainer of an existing extension, would you be interested in writing a pull request to have your extension support roundtrip parsing?
If you need any assistance, please reach out to @generateui. I'd be happy to help.
If you need any assistance, please reach out to @generateui. I'd be happy to help.

View File

@@ -13,45 +13,39 @@ namespace Markdig.Syntax
{
public static bool TrimStartAndCountNewLines<T>(ref T iterator, out int countNewLines) where T : ICharIterator
{
countNewLines = 0;
var c = iterator.CurrentChar;
bool hasWhitespaces = false;
while (c.IsWhitespace())
{
if (c == '\n')
{
countNewLines++;
}
hasWhitespaces = true;
c = iterator.NextChar();
}
return hasWhitespaces;
return TrimStartAndCountNewLines(ref iterator, out countNewLines, out _);
}
public static bool TrimStartAndCountNewLines<T>(ref T iterator, out int countNewLines, out NewLine firstNewline) where T : ICharIterator
public static bool TrimStartAndCountNewLines<T>(ref T iterator, out int countNewLines, out NewLine lastLine) where T : ICharIterator
{
countNewLines = 0;
var c = iterator.CurrentChar;
bool hasWhitespaces = false;
firstNewline = NewLine.None;
while (c.IsWhitespace())
lastLine = NewLine.None;
while (c != '\0' && c.IsWhitespace())
{
if (c == '\n' || c == '\r')
{
if (c == '\r' && iterator.PeekChar() == '\n' && firstNewline != NewLine.None)
if (c == '\r' && iterator.PeekChar() == '\n')
{
firstNewline = NewLine.CarriageReturnLineFeed;
lastLine = NewLine.CarriageReturnLineFeed;
iterator.SkipChar(); // skip \n
}
else if (c == '\n' && firstNewline != NewLine.None)
else if (c == '\n')
{
firstNewline = NewLine.LineFeed;
lastLine = NewLine.LineFeed;
}
else if (c == '\r' && firstNewline != NewLine.None)
else if (c == '\r')
{
firstNewline = NewLine.CarriageReturn;
lastLine = NewLine.CarriageReturn;
}
countNewLines++;
}
else
{
// reset last line if if have a whitespace after
lastLine = NewLine.None;
}
hasWhitespaces = true;
c = iterator.NextChar();
}

View File

@@ -50,7 +50,7 @@ namespace Markdig.Syntax
/// <summary>
/// Gets or sets the whitespace after the # character when <see cref="IsSetext"/> is false.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
public StringSlice TriviaAfterAtxHeaderChar { get; set; }

View File

@@ -61,13 +61,13 @@ namespace Markdig.Syntax
/// <summary>
/// Trivia occurring before this block
/// </summary>
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise <see cref="StringSlice.IsEmpty"/>.
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise <see cref="StringSlice.IsEmpty"/>.
StringSlice TriviaBefore { get; set; }
/// <summary>
/// Trivia occurring after this block
/// </summary>
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise <see cref="StringSlice.IsEmpty"/>.
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise <see cref="StringSlice.IsEmpty"/>.
StringSlice TriviaAfter { get; set; }
}
}

View File

@@ -24,7 +24,7 @@ namespace Markdig.Syntax
/// <summary>
/// Gets or sets the trivia after the <see cref="FencedChar"/>.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
StringSlice TriviaAfterFencedChar { get; set; }
@@ -37,14 +37,14 @@ namespace Markdig.Syntax
/// <summary>
/// Non-escaped <see cref="Info"/> exactly as in source markdown.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
StringSlice UnescapedInfo { get; set; }
/// <summary>
/// Gets or sets the trivia after the <see cref="Info"/>.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
StringSlice TriviaAfterInfo { get; set; }
@@ -57,28 +57,28 @@ namespace Markdig.Syntax
/// <summary>
/// Non-escaped <see cref="Arguments"/> exactly as in source markdown.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
StringSlice UnescapedArguments { get; set; }
/// <summary>
/// Gets or sets the trivia after the <see cref="Arguments"/>.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
StringSlice TriviaAfterArguments { get; set; }
/// <summary>
/// Newline of the line with the opening fenced chars.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
NewLine InfoNewLine { get; set; }
/// <summary>
/// Trivia before the closing fenced chars
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
StringSlice TriviaBeforeClosingFence { get; set; }
@@ -91,7 +91,7 @@ namespace Markdig.Syntax
/// <summary>
/// Newline after the last line, which is always the line containing the closing fence chars.
/// "Inherited" from <see cref="Block.NewLine"/>.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
NewLine NewLine { get; set; }

View File

@@ -34,7 +34,7 @@ namespace Markdig.Syntax.Inlines
/// <summary>
/// Gets or sets the <see cref="Label"/> with trivia.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
public StringSlice LabelWithTrivia { get; set; }

View File

@@ -167,6 +167,13 @@ namespace Markdig.Syntax
/// <typeparam name="T">Type of the text</typeparam>
/// <param name="text">The text.</param>
/// <param name="block">The block.</param>
/// <param name="triviaBeforeLabel"></param>
/// <param name="labelWithTrivia"></param>
/// <param name="triviaBeforeUrl"></param>
/// <param name="unescapedUrl"></param>
/// <param name="triviaBeforeTitle"></param>
/// <param name="unescapedTitle"></param>
/// <param name="triviaAfterTitle"></param>
/// <returns><c>true</c> if parsing is successful; <c>false</c> otherwise</returns>
public static bool TryParseTrivia<T>(
ref T text,

View File

@@ -30,7 +30,7 @@ namespace Markdig.Syntax
/// <summary>
/// Gets or sets the bullet as parsed in the source document.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
public StringSlice SourceBullet { get; set; }

View File

@@ -24,7 +24,7 @@ namespace Markdig.Syntax
/// <summary>
/// Gets or sets the trivia per line of this QuoteBlock.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="StringSlice.IsEmpty"/>.
/// </summary>
public List<QuoteBlockLine> QuoteLines { get; } = new ();
@@ -37,14 +37,14 @@ namespace Markdig.Syntax
/// <summary>
/// Represents trivia per line part of a QuoteBlock.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="QuoteBlock.QuoteLines"/> is empty.
/// </summary>
public class QuoteBlockLine
{
/// <summary>
/// Gets or sets trivia occuring before the first quote character.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="QuoteBlock.QuoteLines"/> is empty.
/// </summary>
public StringSlice TriviaBefore { get; set; }
@@ -52,14 +52,14 @@ namespace Markdig.Syntax
/// <summary>
/// True when this QuoteBlock line has a quote character. False when
/// this line is a "lazy line".
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="QuoteBlock.QuoteLines"/> is empty.
/// </summary>
public bool QuoteChar { get; set; }
/// <summary>
/// True if a space is parsed right after the quote character.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="QuoteBlock.QuoteLines"/> is empty.
/// </summary>
public bool HasSpaceAfterQuoteChar { get; set; }
@@ -68,14 +68,14 @@ namespace Markdig.Syntax
/// Gets or sets the trivia after the the space after the quote character.
/// The first space is assigned to <see cref="HasSpaceAfterQuoteChar"/>, subsequent
/// trivia is assigned to this property.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="QuoteBlock.QuoteLines"/> is empty.
/// </summary>
public StringSlice TriviaAfter { get; set; }
/// <summary>
/// Gets or sets the newline of this QuoeBlockLine.
/// Trivia: only parsed when <see cref="MarkdownParser.TrackTrivia"/> is enabled, otherwise
/// Trivia: only parsed when <see cref="MarkdownPipeline.TrackTrivia"/> is enabled, otherwise
/// <see cref="QuoteBlock.QuoteLines"/> is empty.
/// </summary>
public NewLine NewLine { get; set; }

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@@ -1,20 +1,19 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace UnicodeNormDApp
{
class Program
{
static void Main(string[] args)
static async Task Main(string[] args)
{
var httpClient = new WebClient();
var data = httpClient.DownloadString("http://www.unicode.org/Public/UCD/latest/ucd/NormalizationTest.txt");
using var httpClient = new HttpClient();
var data = await httpClient.GetStringAsync("http://www.unicode.org/Public/UCD/latest/ucd/NormalizationTest.txt");
var stringReader = new StringReader(data);

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
</Project>

View File

@@ -1,6 +1,6 @@
{
"sdk": {
"version": "5.0.100",
"version": "6.0.100",
"rollForward": "latestMinor",
"allowPrerelease": false
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>