Compare commits

...

43 Commits

Author SHA1 Message Date
Alexandre Mutel
3030b72f78 Bump to 0.23.0 2021-01-16 08:35:47 +01:00
Alexandre Mutel
d1784676b2 Rename AutolineInlineParser to AutolinkInlineParser 2021-01-16 08:34:45 +01:00
Alexandre Mutel
47e49f0a4f Add test documentation for root namespace 2021-01-16 08:28:20 +01:00
Alexandre Mutel
0bfc456509 Merge pull request #502 from yufeih/code-inline-plain-text
Fix CodeInline to plain text incorrect escape
2021-01-14 20:33:17 +01:00
Alexandre Mutel
8e14997bc1 Merge pull request #500 from MihaZupan/depth-limit
Add depth limits to avoid pathological-case parsing times/StackOverflows
2021-01-14 20:32:00 +01:00
Yufei Huang
a8ec3c1a48 Fix CodeInline to plain text incorrect escape 2021-01-12 16:11:31 +08:00
MihaZupan
f6f617a746 Add depth limits 2021-01-07 23:16:25 +01:00
Alexandre Mutel
3d65b9f6b6 Upgrade webapp settings 2020-12-22 14:36:26 +01:00
Alexandre Mutel
5f7d93be52 Use net5.0 2020-12-22 12:30:10 +01:00
Alexandre Mutel
3ec787687c Force not to use a pre-release in global.json 2020-12-22 11:16:38 +01:00
Alexandre Mutel
e523dfd7f4 Update the logo for the NuGet package 2020-12-02 08:04:32 +01:00
Alexandre Mutel
412500158c Merge pull request #492 from ilich/master
Added a reference to WebStoating.Markdig.Prism
2020-12-02 07:56:38 +01:00
Alexandre Mutel
fc942b4d01 Update logo 2020-12-02 07:55:18 +01:00
Ilya Verbitskiy
d1d64842ca Added a reference to WebStoating.Markdig.Prism 2020-11-10 16:40:19 +08:00
Alexandre Mutel
930eee383f Use dotnet 3.1 for SpecFileGen 2020-11-08 11:06:16 +01:00
Alexandre Mutel
87c45db46b Use latest dotnet 3.1.x SDK 2020-11-08 10:52:17 +01:00
Alexandre Mutel
751c79fce4 Bump to 0.22.0 2020-10-05 08:20:45 +02:00
Alexandre Mutel
4dc8cc3977 Bump packages in tests 2020-10-05 08:20:31 +02:00
Alexandre Mutel
a1891e2984 Fix coverlet 2020-10-05 08:10:53 +02:00
Alexandre Mutel
ff0637993c Merge branch 'pr/n471_master' 2020-10-05 07:59:19 +02:00
Alexandre Mutel
8b64ce456f Fix quoteblock with setexheading when no lazy continuations are involved 2020-10-05 07:58:48 +02:00
Alexandre Mutel
a781ae1e5b Change tests to exe 2020-10-05 07:57:16 +02:00
Alexandre Mutel
2e5007241d Delay parsing of all specs in the tests itself instead of using static to restore the debuggability of markdig 2020-10-05 07:55:24 +02:00
Alexandre Mutel
cf6d98b7f8 Update tests 2020-10-05 07:54:13 +02:00
Ham Vocke
ccb7e8edfa add failing test, partial fix for setext headings in blockquotes
attempts to fix #465
2020-10-03 07:32:03 +02:00
Alexandre Mutel
db25c1db43 Merge pull request #473 from aloisdg/patch-1
Add a link to try the example
2020-10-03 07:22:22 +02:00
Alexandre Mutel
5db90ede4b Merge pull request #470 from iskcal/iss469
Fix issue 469
2020-10-03 07:21:34 +02:00
Alexandre Mutel
fef1ad3563 Merge pull request #474 from Wurstfried/pubFirstParentOfType
Make Inline.FirstParentOfType public
2020-10-03 07:20:20 +02:00
Alexandre Mutel
e9302d93bd Merge branch 'master' into pubFirstParentOfType 2020-10-03 07:15:02 +02:00
Alexandre Mutel
4704c49fbf Merge pull request #478 from yufeih/fix-476
Fix tel: treated as autolink
2020-10-03 07:12:36 +02:00
Alexandre Mutel
aca70e5c9a Merge pull request #479 from yufeih/fix-ci
Fix NETSDK1045 CI build failure
2020-10-03 06:34:36 +02:00
Yufei Huang
da5eff075d Fix NETSDK1045 CI build failure 2020-09-30 16:32:37 +08:00
Yufei Huang
971207e942 Fix tel: treated as autolink 2020-09-30 16:23:46 +08:00
iskcal
fb942f9810 fix typo 2020-09-15 19:31:29 +08:00
Sebastian Raffel
25a227fffd CI: Use dotnet SDK 3.1.402 2020-09-13 10:19:54 +02:00
Sebastian Raffel
2be8cd4aa7 Make Inline.FirstParentOfType public 2020-09-13 08:05:34 +02:00
Alois
569b80befe Add a link to try the example 2020-09-09 18:10:36 +02:00
iskcal
0b8b14490e fix issue 469 2020-08-25 13:05:44 +08:00
Alexandre Mutel
c59fd5c651 Merge pull request #468 from yufeih/parentblock
Add ParentBlock property to ContainerInline
2020-08-18 09:59:18 +02:00
Alexandre Mutel
4893e2b177 Merge pull request #467 from yufeih/container-block-parent
Set Parent in ContainerBlock.set[index] method
2020-08-18 09:44:41 +02:00
Yufei Huang
b30b219237 Add ParentBlock property to ContainerInline 2020-08-18 15:42:29 +08:00
Yufei Huang
d6c627aa88 Address PR feedback 2020-08-18 15:40:27 +08:00
Yufei Huang
a26f4298a4 Set Parent in ContainerBlock.set[index] method 2020-08-18 14:55:15 +08:00
84 changed files with 443 additions and 348 deletions

View File

@@ -20,16 +20,16 @@ jobs:
- name: Checkout
uses: actions/checkout@v1
- name: Install .NET Core
- name: Install .NET 5.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.0.100
dotnet-version: '5.0.x'
- name: Build (Release)
run: dotnet build src -c Release
- name: SpecFileGen
run: dotnet src/SpecFileGen/bin/Release/netcoreapp2.1/SpecFileGen.dll
run: dotnet src/SpecFileGen/bin/Release/net5.0/SpecFileGen.dll
- name: Test (Release)
run: dotnet test src -c Release
@@ -38,14 +38,14 @@ jobs:
run: dotnet test src -c Debug
- name: Coverlet
run: dotnet test src -c Release -f netcoreapp2.1 /p:Include=\"[${{env.PROJECT_NAME}}]*\" /p:CollectCoverage=true /p:CoverletOutputFormat=lcov
run: dotnet test src -c Release -f net5.0 /p:Include=\"[${{env.PROJECT_NAME}}]*\" /p:CollectCoverage=true /p:CoverletOutputFormat=lcov
- name: Coveralls Upload
uses: coverallsapp/github-action@v1.0.1
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: src/${{env.PROJECT_NAME}}.Tests/coverage.netcoreapp2.1.info
path-to-lcov: src/${{env.PROJECT_NAME}}.Tests/coverage.info
- name: Pack
run: dotnet pack src -c Release

View File

@@ -1,5 +1,19 @@
# Changelog
## 0.23.0 (16 Jan 2021)
- Add depth limits to avoid pathological-case parsing times/StackOverflows (#500)
- Breaking change: rename AutolineInlineParser to AutolinkInlineParser
## 0.22.1 (2 Dec 2020)
- Update logo for NuGet package
## 0.22.0 (05 Oct 2020)
- Fix Setext headings in block quotes.
- Fix tel: treated as autolink ([PR #478](https://github.com/lunet-io/markdig/pull/478)
- Make Inline.FirstParentOfType public ([PR #474](https://github.com/lunet-io/markdig/pull/474)
- Fix `&` to be parsed as a punctuation while it was detected as a html entity in certain cases ([PR #471](https://github.com/lunet-io/markdig/pull/471)
- Add ParentBlock property to ContainerInline ([PR #468](https://github.com/lunet-io/markdig/pull/468)
## 0.21.1 (17 Aug 2020)
- Fix Markdig.Signed on GitHub Actions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -14,11 +14,11 @@
viewBox="0 0 192 192"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="markdig.svg"
inkscape:export-filename="C:\Code\lunet-io\markdig\markdig.png"
inkscape:export-xdpi="93.400002"
inkscape:export-ydpi="93.400002">
inkscape:export-filename="C:\code\lunet\markdig\img\markdig.png"
inkscape:export-xdpi="256"
inkscape:export-ydpi="256">
<defs
id="defs4" />
<sodipodi:namedview
@@ -28,16 +28,16 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.4374889"
inkscape:cx="174.14769"
inkscape:cy="93.189838"
inkscape:zoom="6.275557"
inkscape:cx="81.620292"
inkscape:cy="119.68434"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1377"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-width="3840"
inkscape:window-height="2066"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
units="px" />
<metadata
@@ -48,7 +48,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@@ -59,13 +59,8 @@
style="display:inline"
transform="translate(0,-860.36216)">
<path
style="fill:#000000"
d="M 75.009766 60.486328 L 34.648438 122.74414 C 33.793918 123.59769 37.647081 134.96384 37.052734 136.09766 L 4.0234375 177.69727 C 2.4142291 180.39677 3.2900484 182.21846 4.8730469 183.84766 C 5.9214414 184.93636 6.6591287 186.06887 8.3828125 185.67188 C 9.0750612 185.50987 10.104893 185.27338 10.875 184.76758 L 52.806641 151.81445 C 53.912466 151.23195 64.44071 154.77813 65.289062 153.92383 L 126.45312 111.46875 L 75.009766 60.486328 z M 89.632812 84.769531 L 103.77539 98.912109 L 79.027344 123.66016 L 86.238281 130.87109 L 48.621094 139.92383 L 57.435547 102.30859 L 64.884766 109.51758 L 89.632812 84.769531 z "
transform="translate(0,860.36216)"
id="path4140" />
<path
style="fill:#000000;fill-opacity:1"
d="m 111.18463,862.06984 c -1.98231,0 -3.96282,0.78454 -5.54759,2.38445 L 88.200894,881.94537 75.123368,868.82653 c -3.169466,-3.18017 -7.92567,-3.18017 -11.095213,0 -3.169466,3.18017 -3.169466,7.95108 0,11.13109 l 13.077526,13.11885 -11.095212,10.73223 82.031621,81.49227 11.09525,-11.13109 13.87084,13.51554 c 1.57915,1.59105 3.56724,2.38445 5.54759,2.38445 1.98231,0 3.96285,-0.78453 5.54762,-2.38445 3.16947,-3.18017 3.16947,-7.95111 0,-11.13109 l -13.87083,-13.11884 17.43611,-17.09442 c 1.17983,-1.59105 1.98231,-3.5788 1.98231,-5.96329 0,-1.98351 -0.79863,-3.97554 -2.37816,-5.56446 l -70.54053,-70.35856 c -1.57914,-1.59105 -3.56724,-2.38446 -5.54758,-2.38446 z m 15.86949,20.75826 9.50139,9.5291 -4.04453,23.11372 23.04691,-4.05619 9.50138,9.5291 -36.8437,36.95052 -9.50135,-9.5291 21.13082,-21.19197 -23.04672,4.05619 4.04453,-23.11396 -21.131009,21.19198 -9.501383,-9.5291 36.843662,-36.95048 z"
style="fill:#006680;fill-opacity:1;stroke-width:1.09204066"
d="m 34.5307,873.24547 c -1.506145,1.5557 -2.414834,3.72567 -2.403331,6.22497 l 0.04173,27.41047 -19.903814,-0.0324 c -4.824408,-0.009 -8.4381391,3.7242 -8.4300642,8.70738 0.00817,4.98312 3.6330369,8.72727 8.4573232,8.73554 l 19.903821,0.0324 -0.275791,17.12991 124.244306,-0.42328 -0.0273,-17.44297 20.80798,-0.27883 c 2.4087,0.009 4.52205,-0.92824 6.02671,-2.48239 1.50614,-1.55569 2.41486,-3.72569 2.40336,-6.225 -0.009,-4.98311 -3.63306,-8.7273 -8.45733,-8.73554 l -20.50656,0.59015 0.25961,-27.09914 c -0.31244,-2.17456 -1.213,-4.36429 -3.02472,-6.23561 -1.50705,-1.55665 -3.62738,-2.49321 -6.03475,-2.50058 l -107.054134,0.14282 c -2.408688,-0.009 -4.522059,0.92823 -6.026707,2.48237 z m 27.829505,3.83665 14.459233,0.0217 14.488635,21.31347 14.429017,-21.27019 14.45922,0.0217 0.0811,57.91281 -14.4592,-0.0217 -0.0464,-33.21443 -14.428869,21.27005 -14.488819,-21.31366 0.04632,33.21458 -14.459226,-0.0218 -0.08116,-57.91275 z"
id="path4142"
inkscape:connector-curvature="0" />
<rect
@@ -95,7 +90,7 @@
<flowRoot
xml:space="preserve"
id="flowRoot4797"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
style="font-style:normal;font-weight:normal;line-height:0.01%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
transform="matrix(0.1746417,0,0,0.1459084,499.69318,366.39614)"><flowRegion
id="flowRegion4799"><rect
id="rect4801"
@@ -103,7 +98,8 @@
height="618.71844"
x="959.01355"
y="-976.15039" /></flowRegion><flowPara
id="flowPara4803" /></flowRoot> <g
id="flowPara4803"
style="font-size:40px;line-height:1.25"> </flowPara></flowRoot> <g
id="g4833"
transform="matrix(0.09510056,0,0,0.09061765,496.09965,368.83934)">
<rect
@@ -114,18 +110,20 @@
y="0"
style="fill:#ffffff" />
</g>
<path
inkscape:connector-curvature="0"
id="path4886"
d="m 111.18463,862.06984 c -1.98231,0 -3.96282,0.78454 -5.54759,2.38445 L 88.200894,881.94537 75.123368,868.82653 c -3.169466,-3.18017 -7.92567,-3.18017 -11.095213,0 -3.169466,3.18017 -3.169466,7.95108 0,11.13109 l 13.077526,13.11885 -11.095212,10.73223 82.031621,81.49227 11.09525,-11.13109 13.87084,13.51554 c 1.57915,1.59105 3.56724,2.38445 5.54759,2.38445 1.98231,0 3.96285,-0.78453 5.54762,-2.38445 3.16947,-3.18017 3.16947,-7.95111 0,-11.13109 l -13.87083,-13.11884 17.43611,-17.09442 c 1.17983,-1.59105 1.98231,-3.5788 1.98231,-5.96329 0,-1.98351 -0.79863,-3.97554 -2.37816,-5.56446 l -70.54053,-70.35856 c -1.57914,-1.59105 -3.56724,-2.38446 -5.54758,-2.38446 z m 15.86949,20.75826 9.50139,9.5291 -4.04453,23.11372 23.04691,-4.05619 9.50138,9.5291 -36.8437,36.95052 -9.50135,-9.5291 21.13082,-21.19197 -23.04672,4.05619 4.04453,-23.11396 -21.131009,21.19198 -9.501383,-9.5291 36.843662,-36.95048 z"
style="fill:#000000;fill-opacity:1" />
<g
transform="translate(234.63786,787.55486)"
id="g4170" />
<path
id="path4225"
transform="translate(0,860.36216)"
d="M 75.009766 60.486328 L 34.648438 122.74414 C 33.793918 123.59769 37.647081 134.96384 37.052734 136.09766 L 4.0234375 177.69727 C 2.4142291 180.39677 3.2900484 182.21846 4.8730469 183.84766 C 5.9214414 184.93636 6.6591287 186.06887 8.3828125 185.67188 C 9.0750612 185.50987 10.104893 185.27338 10.875 184.76758 L 52.806641 151.81445 C 53.912466 151.23195 64.44071 154.77813 65.289062 153.92383 L 126.45312 111.46875 L 75.009766 60.486328 z M 89.632812 84.769531 L 103.77539 98.912109 L 79.027344 123.66016 L 86.238281 130.87109 L 48.621094 139.92383 L 57.435547 102.30859 L 64.884766 109.51758 L 89.632812 84.769531 z "
style="fill:#000000" />
sodipodi:nodetypes="cccccccccccccc"
inkscape:connector-curvature="0"
id="path826"
d="m 45.058494,943.54749 20.013843,88.87081 c -8.87e-4,1.4793 13.909884,7.9857 28.77803,7.9868 14.868153,0 27.732473,-6.0454 27.727033,-7.5199 l 17.1004,-89.73688 z m 35.561125,8.36596 h 25.853221 l 10e-6,42.86491 h 13.18189 l -26.108514,40.41734 -26.324515,-40.20925 13.397908,-0.20809 z"
style="fill:#ff6600;stroke-width:1.2582258" />
<path
style="fill:#c83737;stroke-width:1.2582258"
d="m 45.058494,943.54749 20.013843,88.87081 c -8.87e-4,1.4793 13.909884,7.9857 28.77803,7.9868 14.868153,0 27.732473,-6.0454 27.727033,-7.5199 l 17.1004,-89.73688 z m 35.561125,8.36596 h 25.853221 l 10e-6,42.86491 h 13.18189 l -26.108514,40.41734 -26.324515,-40.20925 13.397908,-0.20809 z"
id="path828"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -59,6 +59,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 Prism.js**: `WebStoating.Markdig.Prism`](https://github.com/ilich/Markdig.Prism)
- [**Embedded C# scripting**: `Markdig.Extensions.ScriptCs`](https://github.com/macaba/Markdig.Extensions.ScriptCs)
## Documentation
@@ -94,6 +95,8 @@ var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
var result = Markdown.ToHtml("This is a text with some *emphasis*", pipeline);
```
[Try it online!](https://dotnetfiddle.net/GoZXyI)
You can have a look at the [MarkdownExtensions](https://github.com/lunet-io/markdig/blob/master/src/Markdig/MarkdownExtensions.cs) that describes all actionable extensions (by modifying the MarkdownPipeline)
## Build

View File

@@ -36,12 +36,12 @@
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.6" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.10.6" />
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.12.1" />
<PackageReference Include="CommonMark.NET" Version="0.15.1" />
<PackageReference Include="MarkdownSharp" Version="1.13.0.0" />
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="0.8.31-beta" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="1.0.41.0" />
<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" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Markdig\Markdig.csproj" />

View File

@@ -1,19 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net452;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<OutputType>Library</OutputType>
<TargetFramework>net5.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<StartupObject>Markdig.Tests.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="2.8.1">
<PackageReference Include="coverlet.msbuild" Version="2.9.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -62,6 +62,29 @@ namespace Markdig.Tests
}
}
[Theory]
[TestCase('[', 9 * 1024, true, false)]
[TestCase('[', 11 * 1024, true, true)]
[TestCase('[', 100, false, false)]
[TestCase('[', 150, false, true)]
[TestCase('>', 100, true, false)]
[TestCase('>', 150, true, true)]
public void GuardsAgainstHighlyNestedNodes(char c, int count, bool parseOnly, bool shouldThrow)
{
var markdown = new string(c, count);
TestDelegate test = parseOnly ? () => Markdown.Parse(markdown) : () => Markdown.ToHtml(markdown);
if (shouldThrow)
{
Exception e = Assert.Throws<ArgumentException>(test);
Assert.True(e.Message.Contains("depth limit"));
}
else
{
test();
}
}
[Test]
public void IsIssue356Corrected()
{

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Headings
@@ -79,15 +78,15 @@ namespace Markdig.Tests.Specs.Normalize.Headings
// Heading
// =======
//
// Text after two newlines
// Text after two newlines 1
//
// Should be rendered as:
// # Heading
//
// Text after two newlines
// Text after two newlines 1
Console.WriteLine("Example 3\nSection Headings\n");
TestNormalize.TestSpec("Heading\n=======\n\nText after two newlines", "# Heading\n\nText after two newlines", "");
TestNormalize.TestSpec("Heading\n=======\n\nText after two newlines 1", "# Heading\n\nText after two newlines 1", "");
}
}
}

View File

@@ -40,9 +40,9 @@ Text after two newlines
Heading
=======
Text after two newlines
Text after two newlines 1
.
# Heading
Text after two newlines
Text after two newlines 1
````````````````````````````````

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Sample

View File

@@ -0,0 +1,19 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
using System;
namespace Markdig.Tests
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Run NUnit tests runner with this");
// Uncomment the following line to debug a specific tests more easily
//var tests = new Specs.CommonMarkV_0_29.TestLeafBlocksSetextHeadings();
//tests.LeafBlocksSetextHeadings_Example063();
}
}
}

View File

@@ -1,4 +1,3 @@
// Generated: 2019-05-15 02:46:55
// --------------------------------
// Abbreviations

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Auto Identifiers

View File

@@ -1,4 +1,3 @@
// Generated: 2020-07-21 22:02:10
// --------------------------------
// Auto Links
@@ -61,15 +60,17 @@ namespace Markdig.Tests.Specs.AutoLinks
// This is not a ftp:/test.com
// And not a mailto:emailtoto.com
// And not a plain www. or a www.x
// And not a tel:
//
// Should be rendered as:
// <p>This is not a http:/www.google.com URL and https:/www.google.com
// This is not a ftp:/test.com
// And not a mailto:emailtoto.com
// And not a plain www. or a www.x</p>
// And not a plain www. or a www.x
// And not a tel:</p>
Console.WriteLine("Example 2\nSection Extensions / AutoLinks\n");
TestParser.TestSpec("This is not a http:/www.google.com URL and https:/www.google.com\nThis is not a ftp:/test.com\nAnd not a mailto:emailtoto.com\nAnd not a plain www. or a www.x ", "<p>This is not a http:/www.google.com URL and https:/www.google.com\nThis is not a ftp:/test.com\nAnd not a mailto:emailtoto.com\nAnd not a plain www. or a www.x</p>", "autolinks|advanced");
TestParser.TestSpec("This is not a http:/www.google.com URL and https:/www.google.com\nThis is not a ftp:/test.com\nAnd not a mailto:emailtoto.com\nAnd not a plain www. or a www.x \nAnd not a tel:", "<p>This is not a http:/www.google.com URL and https:/www.google.com\nThis is not a ftp:/test.com\nAnd not a mailto:emailtoto.com\nAnd not a plain www. or a www.x\nAnd not a tel:</p>", "autolinks|advanced");
}
// Previous character must be a punctuation or a valid space (tab, space, new line):

View File

@@ -33,11 +33,13 @@ This is not a http:/www.google.com URL and https:/www.google.com
This is not a ftp:/test.com
And not a mailto:emailtoto.com
And not a plain www. or a www.x
And not a tel:
.
<p>This is not a http:/www.google.com URL and https:/www.google.com
This is not a ftp:/test.com
And not a mailto:emailtoto.com
And not a plain www. or a www.x</p>
And not a plain www. or a www.x
And not a tel:</p>
````````````````````````````````
Previous character must be a punctuation or a valid space (tab, space, new line):

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-15 05:23:49
// --------------------------------
// Bootstrap

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-12 15:26:42
// --------------------------------
// CommonMark v. 0.29
@@ -14925,6 +14924,29 @@ namespace Markdig.Tests.Specs.CommonMarkV_0_29
Console.WriteLine("Example 649\nSection Inlines / Textual content\n");
TestParser.TestSpec("Multiple spaces", "<p>Multiple spaces</p>", "");
}
// Within a blockquote a setext heading takes precedence
// over a thematic break:
[Test]
public void InlinesTextualContent_Example650()
{
// Example 650
// Section: Inlines / Textual content
//
// The following Markdown:
// > Foo
// > ---
// > bar
//
// Should be rendered as:
// <blockquote>
// <h2>Foo</h2>
// <p>bar</p>
// </blockquote>
Console.WriteLine("Example 650\nSection Inlines / Textual content\n");
TestParser.TestSpec("> Foo\n> ---\n> bar", "<blockquote>\n<h2>Foo</h2>\n<p>bar</p>\n</blockquote>", "");
}
// <!-- END TESTS -->
//
// # Appendix: A parsing strategy

View File

@@ -9368,6 +9368,20 @@ Multiple spaces
<p>Multiple spaces</p>
````````````````````````````````
Within a blockquote a setext heading takes precedence
over a thematic break:
```````````````````````````````` example
> Foo
> ---
> bar
.
<blockquote>
<h2>Foo</h2>
<p>bar</p>
</blockquote>
````````````````````````````````
<!-- END TESTS -->

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Custom Containers

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-15 05:06:35
// --------------------------------
// Definition Lists

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Diagrams

View File

@@ -1,4 +1,3 @@
// Generated: 2020-01-13 21:08:58
// --------------------------------
// Emoji

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Emphasis Extra

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Figures, Footers and Cites

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-15 05:33:49
// --------------------------------
// Footnotes

View File

@@ -1,4 +1,3 @@
// Generated: 2019-08-01 13:57:17
// --------------------------------
// Generic Attributes

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-15 05:25:26
// --------------------------------
// Globalization

View File

@@ -1,4 +1,3 @@
// Generated: 2020-04-20 07:21:20
// --------------------------------
// Grid Tables

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Hardline Breaks

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-15 05:30:00
// --------------------------------
// Jira Links

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// List Extras

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Math

View File

@@ -1,4 +1,3 @@
// Generated: 2020-05-12 19:59:34
// --------------------------------
// Media

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// No Html

View File

@@ -1,4 +1,3 @@
// Generated: 2020-07-30 15:47:38
// --------------------------------
// GFM Pipe Tables

View File

@@ -1,4 +1,3 @@
// Generated: 2020-07-30 15:32:13
// --------------------------------
// Pipe Tables

View File

@@ -1,4 +1,3 @@
// Generated: 2019-08-01 12:33:23
// --------------------------------
// Smarty Pants

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Task Lists

View File

@@ -1,4 +1,3 @@
// Generated: 2019-04-05 16:06:14
// --------------------------------
// Yaml

View File

@@ -47,12 +47,14 @@ namespace Markdig.Tests
container.Insert(0, one);
Assert.AreEqual(1, container.Count);
Assert.AreSame(container[0], one);
Assert.AreSame(container, one.Parent);
var two = new ParagraphBlock();
container.Insert(1, two);
Assert.AreEqual(2, container.Count);
Assert.AreSame(container[0], one);
Assert.AreSame(container[1], two);
Assert.AreSame(container, two.Parent);
var three = new ParagraphBlock();
container.Insert(0, three);
@@ -60,11 +62,31 @@ namespace Markdig.Tests
Assert.AreSame(container[0], three);
Assert.AreSame(container[1], one);
Assert.AreSame(container[2], two);
Assert.AreSame(container, three.Parent);
Assert.Throws<ArgumentNullException>(() => container.Insert(0, null));
Assert.Throws<ArgumentOutOfRangeException>(() => container.Insert(4, new ParagraphBlock()));
Assert.Throws<ArgumentOutOfRangeException>(() => container.Insert(-1, new ParagraphBlock()));
Assert.Throws<ArgumentException>(() => container.Insert(0, one)); // one already has a parent
}
[Test]
public void CanBeSet()
{
ContainerBlock container = new MockContainerBlock();
var one = new ParagraphBlock();
container.Insert(0, one);
Assert.AreEqual(1, container.Count);
Assert.AreSame(container[0], one);
Assert.AreSame(container, one.Parent);
var two = new ParagraphBlock();
container[0] = two;
Assert.AreSame(container, two.Parent);
Assert.Null(one.Parent);
Assert.Throws<ArgumentException>(() => container[0] = two); // two already has a parent
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
using NUnit.Framework;
namespace Markdig.Tests
{
public class TestContainerInlines
{
private class MockLeafBlock : LeafBlock
{
public MockLeafBlock()
: base(null)
{
}
}
[Test]
public void CanBeAddedToLeafBlock()
{
var leafBlock1 = new MockLeafBlock();
var one = new ContainerInline();
Assert.Null(one.ParentBlock);
leafBlock1.Inline = one;
Assert.AreSame(leafBlock1, one.ParentBlock);
var two = new ContainerInline();
Assert.Null(two.ParentBlock);
leafBlock1.Inline = two;
Assert.AreSame(leafBlock1, two.ParentBlock);
Assert.Null(one.ParentBlock);
var leafBlock2 = new MockLeafBlock();
Assert.Throws<ArgumentException>(() => leafBlock2.Inline = two);
}
}
}

View File

@@ -10,10 +10,9 @@ namespace Markdig.Tests
[TestFixture]
public class TestDescendantsOrder
{
[Test]
public void TestSchemas()
public static void TestSchemas(MarkdownDocument[] specsSyntaxTrees)
{
foreach (var syntaxTree in TestParser.SpecsSyntaxTrees)
foreach (var syntaxTree in specsSyntaxTrees)
{
AssertIEnumerablesAreEqual(
Descendants_Legacy(syntaxTree),

View File

@@ -124,6 +124,7 @@ namespace Markdig.Tests
[TestCase(",,foo,,", "<extra-comma>foo</extra-comma>")]
[TestCase(",foo,,", "<comma>foo</comma>,")]
[TestCase(",,,foo,,,", "<comma><extra-comma>foo</extra-comma></comma>")]
[TestCase("*foo*&_foo_", "<em>foo</em>&amp;<em>foo</em>")]
[TestCase("!1!", "!1!")]
[TestCase("!!2!!", "<warning>2</warning>")]
[TestCase("!!!3!!!", "<error>3</error>")]

View File

@@ -22,7 +22,27 @@ namespace Markdig.Tests
if (IsContinuousIntegration)
return;
foreach (var specFilePath in SpecsFilePaths)
var specsFilePaths = Directory.GetDirectories(TestsDirectory)
.Where(dir => dir.EndsWith("Specs"))
.SelectMany(dir => Directory.GetFiles(dir)
.Where(file => file.EndsWith(".md", StringComparison.OrdinalIgnoreCase))
.Where(file => file.IndexOf("readme", StringComparison.OrdinalIgnoreCase) == -1))
.ToArray();
var specsMarkdown = new string[specsFilePaths.Length];
var specsSyntaxTrees = new MarkdownDocument[specsFilePaths.Length];
var pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.Build();
for (int i = 0; i < specsFilePaths.Length; i++)
{
string markdown = specsMarkdown[i] = File.ReadAllText(specsFilePaths[i]);
specsSyntaxTrees[i] = Markdown.Parse(markdown, pipeline);
}
foreach (var specFilePath in specsFilePaths)
{
string testFilePath = Path.ChangeExtension(specFilePath, ".generated.cs");
@@ -43,6 +63,8 @@ namespace Markdig.Tests
$"{Path.GetFileName(specFilePath)} has been modified. Run SpecFileGen to regenerate the tests. " +
"If you have modified a specification file, but reverted all changes, ignore this error or revert the 'changed' timestamp metadata on the file.");
}
TestDescendantsOrder.TestSchemas(specsSyntaxTrees);
}
public static void TestSpec(string inputText, string expectedOutputText, string extensions = null, bool plainText = false)
@@ -141,21 +163,7 @@ namespace Markdig.Tests
public static readonly bool IsContinuousIntegration = Environment.GetEnvironmentVariable("CI") != null;
public static readonly string TestsDirectory =
Path.GetFullPath(Path.Combine(Path.GetDirectoryName(typeof(TestParser).Assembly.Location), "../../.."));
/// <summary>
/// Contains absolute paths to specification markdown files (order is the same as in <see cref="SpecsMarkdown"/>)
/// </summary>
public static readonly string[] SpecsFilePaths;
/// <summary>
/// Contains the markdown source for specification files (order is the same as in <see cref="SpecsFilePaths"/>)
/// </summary>
public static readonly string[] SpecsMarkdown;
/// <summary>
/// Contains the markdown syntax tree for specification files (order is the same as in <see cref="SpecsFilePaths"/>)
/// </summary>
public static readonly MarkdownDocument[] SpecsSyntaxTrees;
public static readonly string TestsDirectory = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(typeof(TestParser).Assembly.Location), "../../.."));
static TestParser()
{
@@ -165,26 +173,6 @@ namespace Markdig.Tests
{
TestsDirectory = TestsDirectory.Substring(0, index) + "\\src\\Markdig.Tests";
}
SpecsFilePaths = Directory.GetDirectories(TestsDirectory)
.Where(dir => dir.EndsWith("Specs"))
.SelectMany(dir => Directory.GetFiles(dir)
.Where(file => file.EndsWith(".md", StringComparison.OrdinalIgnoreCase))
.Where(file => file.IndexOf("readme", StringComparison.OrdinalIgnoreCase) == -1))
.ToArray();
SpecsMarkdown = new string[SpecsFilePaths.Length];
SpecsSyntaxTrees = new MarkdownDocument[SpecsFilePaths.Length];
var pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.Build();
for (int i = 0; i < SpecsFilePaths.Length; i++)
{
string markdown = SpecsMarkdown[i] = File.ReadAllText(SpecsFilePaths[i]);
SpecsSyntaxTrees[i] = Markdown.Parse(markdown, pipeline);
}
}
}
}

View File

@@ -21,6 +21,7 @@ namespace Markdig.Tests
[TestCase(/* markdownText: */ "- foo\n- bar\n- baz", /* expected: */ "foo\nbar\nbaz\n")]
[TestCase(/* markdownText: */ "- foo<baz", /* expected: */ "foo<baz\n")]
[TestCase(/* markdownText: */ "- foo&lt;baz", /* expected: */ "foo<baz\n")]
[TestCase(/* markdownText: */ "## foo `bar::baz >`", /* expected: */ "foo bar::baz >\n")]
public void TestPlainEnsureNewLine(string markdownText, string expected)
{
var actual = Markdown.ToPlainText(markdownText);

View File

@@ -1,42 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<PreserveCompilationContext>true</PreserveCompilationContext>
<AssemblyName>Markdig.WebApp</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Markdig.WebApp</PackageId>
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
<ApplicationInsightsResourceId>/subscriptions/b6745039-70e7-4641-994b-5457cb220e2a/resourcegroups/Default-ApplicationInsights-EastUS/providers/microsoft.insights/components/Markdig.WebApp</ApplicationInsightsResourceId>
<ApplicationInsightsAnnotationResourceId>/subscriptions/b6745039-70e7-4641-994b-5457cb220e2a/resourcegroups/Default-ApplicationInsights-EastUS/providers/microsoft.insights/components/Markdig.WebApp</ApplicationInsightsAnnotationResourceId>
<IsPackable>false</IsPackable>
<UserSecretsId>683145f2-53a7-4938-bd96-35e60ac55d95</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<None Update="Views">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.16.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Markdig\Markdig.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.12.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.2.1" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.1" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
namespace Markdig.WebApp
{
@@ -8,14 +9,14 @@ namespace Markdig.WebApp
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

View File

@@ -1,111 +0,0 @@
# Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
# Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
[cmdletbinding(SupportsShouldProcess=$true)]
param($publishProperties=@{}, $packOutput, $pubProfilePath, $nugetUrl)
# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327
$publishModuleVersion = '1.1.0'
function Get-PublishModulePath{
[cmdletbinding()]
param()
process{
$keysToCheck = @('hklm:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\{0}',
'hklm:\SOFTWARE\Microsoft\VisualStudio\{0}',
'hklm:\SOFTWARE\Wow6432Node\Microsoft\VWDExpress\{0}',
'hklm:\SOFTWARE\Microsoft\VWDExpress\{0}'
)
$versions = @('14.0', '15.0')
[string]$publishModulePath=$null
:outer foreach($keyToCheck in $keysToCheck){
foreach($version in $versions){
if(Test-Path ($keyToCheck -f $version) ){
$vsInstallPath = (Get-itemproperty ($keyToCheck -f $version) -Name InstallDir -ErrorAction SilentlyContinue | select -ExpandProperty InstallDir -ErrorAction SilentlyContinue)
if($vsInstallPath){
$installedPublishModulePath = "{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion
if(!(Test-Path $installedPublishModulePath)){
$vsInstallPath = $vsInstallPath + 'VWDExpress'
$installedPublishModulePath = "{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion
}
if(Test-Path $installedPublishModulePath){
$publishModulePath = $installedPublishModulePath
break outer;
}
}
}
}
}
$publishModulePath
}
}
$publishModulePath = Get-PublishModulePath
$defaultPublishSettings = New-Object psobject -Property @{
LocalInstallDir = $publishModulePath
}
function Enable-PackageDownloader{
[cmdletbinding()]
param(
$toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader-$publishModuleVersion\",
$pkgDownloaderDownloadUrl = 'https://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1
process{
if(get-module package-downloader){
remove-module package-downloader | Out-Null
}
if(!(get-module package-downloader)){
if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false }
$expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1')
if(!(Test-Path $expectedPath)){
'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose
(New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath)
}
if(!$expectedPath){throw ('Unable to download package-downloader.psm1')}
'importing module [{0}]' -f $expectedPath | Write-Output
Import-Module $expectedPath -DisableNameChecking -Force
}
}
}
function Enable-PublishModule{
[cmdletbinding()]
param()
process{
if(get-module publish-module){
remove-module publish-module | Out-Null
}
if(!(get-module publish-module)){
$localpublishmodulepath = Join-Path $defaultPublishSettings.LocalInstallDir 'publish-module.psm1'
if(Test-Path $localpublishmodulepath){
'importing module [publish-module="{0}"] from local install dir' -f $localpublishmodulepath | Write-Verbose
Import-Module $localpublishmodulepath -DisableNameChecking -Force
$true
}
}
}
}
try{
if (!(Enable-PublishModule)){
Enable-PackageDownloader
Enable-NuGetModule -name 'publish-module' -version $publishModuleVersion -nugetUrl $nugetUrl
}
'Calling Publish-AspNet' | Write-Verbose
# call Publish-AspNet to perform the publish operation
Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath
}
catch{
"An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error
}

View File

@@ -1,28 +1,9 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:65396/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Markdig.WebApp": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000/api/to_html?text=yes",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
"launchUrl": "api/to_html?text=test"
}
}
}

View File

@@ -30,19 +30,30 @@ namespace Markdig.WebApp
// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddMvc();
}
// 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)
{
//loggerFactory.AddConsole(Configuration.GetSection("Logging"));
//loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

View File

@@ -8,6 +8,7 @@
}
},
"ApplicationInsights": {
"InstrumentationKey": "5d12f113-76b2-41fe-a35a-db454b104bf9"
"InstrumentationKey": "5d12f113-76b2-41fe-a35a-db454b104bf9",
"ConnectionString": "InstrumentationKey=c00ad051-d881-4dc3-b8c1-8718f1b1c0c6;IngestionEndpoint=https://westus2-0.in.applicationinsights.azure.com/"
}
}

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!--
Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380
-->
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>

View File

@@ -147,6 +147,12 @@ namespace Markdig.Extensions.AutoLinks
return false;
}
break;
case 't':
if (string.Equals(link, "tel", StringComparison.OrdinalIgnoreCase))
{
return false;
}
break;
case 'm':
int atIndex = link.IndexOf('@');
if (atIndex == -1 ||

View File

@@ -168,9 +168,7 @@ namespace Markdig.Helpers
return IsZero(c) || IsWhitespace(c);
}
// Note that we are not considering the character & as a punctuation in HTML
// as it is used for HTML entities, print unicode, so we assume that when we have a `&`
// it is more likely followed by a valid HTML Entity that represents a non punctuation
// Check if a char is a space or a punctuation
public static void CheckUnicodeCategory(this char c, out bool space, out bool punctuation)
{
// Credits: code from CommonMark.NET
@@ -179,7 +177,7 @@ namespace Markdig.Helpers
if (c <= 'ÿ')
{
space = c == '\0' || c == ' ' || (c >= '\t' && c <= '\r') || c == '\u00a0' || c == '\u0085';
punctuation = c == '\0' || (c >= 33 && c <= 47 && c != 38) || (c >= 58 && c <= 64) || (c >= 91 && c <= 96) || (c >= 123 && c <= 126);
punctuation = c == '\0' || (c >= 33 && c <= 47) || (c >= 58 && c <= 64) || (c >= 91 && c <= 96) || (c >= 123 && c <= 126);
}
else
{

View File

@@ -5,6 +5,7 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace Markdig.Helpers
{
@@ -34,6 +35,28 @@ namespace Markdig.Helpers
public static void InvalidOperationException(string message) => throw new InvalidOperationException(message);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CheckDepthLimit(int depth, bool useLargeLimit = false)
{
// Very conservative limit used to limit nesting in the final AST
// Used to avoid a StackOverflow in the recursive rendering process
const int DepthLimit = 128;
// Limit used for reducing the maximum execution time for pathological-case inputs
// Applies to:
// a) inputs that would fail depth checks in the future (for example "[[[[[..." or ">>>>>>...")
// b) very large pipe tables
const int LargeDepthLimit = 10 * 1024;
int limit = useLargeLimit ? LargeDepthLimit : DepthLimit;
if (depth > limit)
DepthLimitExceeded();
[MethodImpl(MethodImplOptions.NoInlining)]
static void DepthLimitExceeded() => throw new ArgumentException("Markdown elements in the input are too deeply nested - depth limit exceeded. Input is most likely not sensible or is a very large table.");
}
public static void ThrowArgumentNullException(ExceptionArgument argument)
{
throw new ArgumentNullException(argument.ToString());

View File

@@ -1,6 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>Markdig</PackageId>
</PropertyGroup>
<Import Project="Markdig.targets" />
<ItemGroup>
<None Remove="readme.md" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="readme.md" LunetApiDotNet="true"/>
</ItemGroup>
</Project>

View File

@@ -4,16 +4,16 @@
<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.21.1</VersionPrefix>
<VersionPrefix>0.23.0</VersionPrefix>
<Authors>Alexandre Mutel</Authors>
<TargetFrameworks>net452;netstandard2.0;netstandard2.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
<PackageTags>Markdown CommonMark md html md2html</PackageTags>
<PackageReleaseNotes>https://github.com/lunet-io/markdig/blob/master/changelog.md</PackageReleaseNotes>
<PackageLicenseExpression>BSD-2-Clause</PackageLicenseExpression>
<PackageIconUrl>https://raw.githubusercontent.com/lunet-io/markdig/master/img/markdig.png</PackageIconUrl>
<PackageIcon>markdig.png</PackageIcon>
<PackageProjectUrl>https://github.com/lunet-io/markdig</PackageProjectUrl>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
<!--Add support for sourcelink-->
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
@@ -46,6 +46,7 @@
</PropertyGroup>
<ItemGroup>
<None Include="../../img/markdig.png" Pack="true" PackagePath="" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.*" PrivateAssets="All"/>
</ItemGroup>

View File

@@ -522,7 +522,7 @@ namespace Markdig
pipeline.BlockParsers.Remove(parser);
}
var inlineParser = pipeline.InlineParsers.Find<AutolineInlineParser>();
var inlineParser = pipeline.InlineParsers.Find<AutolinkInlineParser>();
if (inlineParser != null)
{
inlineParser.EnableHtmlParsing = false;

View File

@@ -44,7 +44,7 @@ namespace Markdig
new EscapeInlineParser(),
new EmphasisInlineParser(),
new CodeInlineParser(),
new AutolineInlineParser(),
new AutolinkInlineParser(),
new LineBreakInlineParser(),
};

View File

@@ -150,6 +150,11 @@ namespace Markdig.Parsers
/// Gets the character position before the indent occurred.
/// </summary>
public int StartBeforeIndent { get; private set; }
/// <summary>
/// Gets a boolean indicating whether the current line being parsed is lazy continuation.
/// </summary>
public bool IsLazy { get; private set; }
/// <summary>
/// Gets the current stack of <see cref="Block"/> being processed.
@@ -577,6 +582,8 @@ namespace Markdig.Parsers
/// </exception>
private void TryContinueBlocks()
{
IsLazy = false;
// Set all blocks non opened.
// They will be marked as open in the following loop
for (int i = 1; i < OpenedBlocks.Count; i++)
@@ -712,6 +719,7 @@ namespace Markdig.Parsers
{
for (int j = 0; j < parsers.Length; j++)
{
IsLazy = false;
var blockParser = parsers[j];
if (Line.IsEmpty)
{
@@ -731,9 +739,9 @@ namespace Markdig.Parsers
continue;
}
bool isLazyParagraph = blockParser is ParagraphBlockParser && lastBlock is ParagraphBlock;
IsLazy = blockParser is ParagraphBlockParser && lastBlock is ParagraphBlock;
var result = isLazyParagraph
var result = IsLazy
? blockParser.TryContinue(this, lastBlock)
: blockParser.TryOpen(this);
@@ -741,7 +749,7 @@ namespace Markdig.Parsers
{
// If we have reached a blank line after trying to parse a paragraph
// we can ignore it
if (isLazyParagraph && IsBlankLine)
if (IsLazy && IsBlankLine)
{
ContinueProcessingLine = false;
break;
@@ -752,7 +760,7 @@ namespace Markdig.Parsers
// Special case for paragraph
UpdateLastBlockAndContainer();
if (isLazyParagraph && CurrentBlock is ParagraphBlock paragraph)
if (IsLazy && CurrentBlock is ParagraphBlock paragraph)
{
Debug.Assert(NewBlocks.Count == 0);
@@ -782,6 +790,8 @@ namespace Markdig.Parsers
// We have a leaf node, we can stop
}
IsLazy = false;
return false;
}

View File

@@ -307,7 +307,7 @@ namespace Markdig.Parsers
private ContainerInline FindLastContainer()
{
var container = Block.Inline;
while (true)
for (int depth = 0; ; depth++)
{
if (container.LastChild is ContainerInline nextContainer && !nextContainer.IsClosed)
{
@@ -315,10 +315,10 @@ namespace Markdig.Parsers
}
else
{
break;
ThrowHelper.CheckDepthLimit(depth, useLargeLimit: true);
return container;
}
}
return container;
}
}
}

View File

@@ -12,12 +12,12 @@ namespace Markdig.Parsers.Inlines
/// An inline parser for parsing <see cref="AutolinkInline"/>.
/// </summary>
/// <seealso cref="InlineParser" />
public class AutolineInlineParser : InlineParser
public class AutolinkInlineParser : InlineParser
{
/// <summary>
/// Initializes a new instance of the <see cref="AutolineInlineParser"/> class.
/// Initializes a new instance of the <see cref="AutolinkInlineParser"/> class.
/// </summary>
public AutolineInlineParser()
public AutolinkInlineParser()
{
OpeningCharacters = new[] {'<'};
EnableHtmlParsing = true;

View File

@@ -191,6 +191,7 @@ namespace Markdig.Parsers
newItem.Container = (ContainerBlock)block;
block.OnProcessInlinesBegin(inlineProcessor);
newItem.Index = 0;
ThrowHelper.CheckDepthLimit(blocks.Count);
blocks.Push(newItem);
goto process_new_block;
}

View File

@@ -38,7 +38,7 @@ namespace Markdig.Parsers
return BlockState.BreakDiscard;
}
if (ParseSetexHeadings && !processor.IsCodeIndent && !(block.Parent is QuoteBlock))
if (!processor.IsCodeIndent && ParseSetexHeadings)
{
return TryParseSetexHeading(processor, block);
}
@@ -86,7 +86,11 @@ namespace Markdig.Parsers
// If we matched a LinkReferenceDefinition before matching the heading, and the remaining
// lines are empty, we can early exit and remove the paragraph
if (!(TryMatchLinkReferenceDefinition(ref paragraph.Lines, state) && paragraph.Lines.Count == 0))
var parent = block.Parent;
bool isSetTextHeading = !state.IsLazy || paragraph.Column == state.Column || !(parent is QuoteBlock || parent is ListItemBlock);
if (!(TryMatchLinkReferenceDefinition(ref paragraph.Lines, state) && paragraph.Lines.Count == 0) && isSetTextHeading)
{
// We discard the paragraph that will be transformed to a heading
state.Discard(paragraph);

View File

@@ -74,7 +74,7 @@ namespace Markdig.Parsers
if (isSetexHeading)
{
var parent = previousParagraph.Parent;
if (parent is QuoteBlock || (parent is ListItemBlock && previousParagraph.Column != processor.Column))
if (previousParagraph.Column != processor.Column && (parent is QuoteBlock || parent is ListItemBlock))
{
isSetexHeading = false;
}

View File

@@ -18,7 +18,14 @@ namespace Markdig.Renderers.Html.Inlines
{
renderer.Write("<code").WriteAttributes(obj).Write(">");
}
renderer.WriteEscape(obj.Content);
if (renderer.EnableHtmlEscape)
{
renderer.WriteEscape(obj.Content);
}
else
{
renderer.Write(obj.Content);
}
if (renderer.EnableHtmlForInline)
{
renderer.Write("</code>");

View File

@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using Markdig.Helpers;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
@@ -18,6 +19,7 @@ namespace Markdig.Renderers
private readonly Dictionary<Type, IMarkdownObjectRenderer> renderersPerType;
private IMarkdownObjectRenderer previousRenderer;
private Type previousObjectType;
internal int childrenDepth = 0;
/// <summary>
/// Initializes a new instance of the <see cref="RendererBase"/> class.
@@ -57,6 +59,8 @@ namespace Markdig.Renderers
return;
}
ThrowHelper.CheckDepthLimit(childrenDepth++);
bool saveIsFirstInContainer = IsFirstInContainer;
bool saveIsLastInContainer = IsLastInContainer;
@@ -70,6 +74,8 @@ namespace Markdig.Renderers
IsFirstInContainer = saveIsFirstInContainer;
IsLastInContainer = saveIsLastInContainer;
childrenDepth--;
}
/// <summary>
@@ -83,6 +89,8 @@ namespace Markdig.Renderers
return;
}
ThrowHelper.CheckDepthLimit(childrenDepth++);
bool saveIsFirstInContainer = IsFirstInContainer;
bool saveIsLastInContainer = IsLastInContainer;
@@ -101,6 +109,8 @@ namespace Markdig.Renderers
IsFirstInContainer = saveIsFirstInContainer;
IsLastInContainer = saveIsLastInContainer;
childrenDepth--;
}
/// <summary>

View File

@@ -101,6 +101,7 @@ namespace Markdig.Renderers
ThrowHelper.InvalidOperationException("Cannot reset this TextWriter instance");
}
childrenDepth = 0;
previousWasLine = true;
indents.Clear();
}

View File

@@ -2,6 +2,7 @@
// 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;
using Markdig.Parsers;
namespace Markdig.Syntax
@@ -79,6 +80,7 @@ namespace Markdig.Syntax
public void UpdateSpanEnd(int spanEnd)
{
// Update parent spans
int depth = 0;
var parent = this;
while (parent != null)
{
@@ -87,7 +89,9 @@ namespace Markdig.Syntax
parent.Span.End = spanEnd;
}
parent = parent.Parent;
depth++;
}
ThrowHelper.CheckDepthLimit(depth, useLargeLimit: true);
}
}
}

View File

@@ -216,6 +216,18 @@ namespace Markdig.Syntax
set
{
if ((uint)index >= (uint)Count) ThrowHelper.ThrowIndexOutOfRangeException();
if (value == null)
ThrowHelper.ArgumentNullException_item();
if (value.Parent != null)
ThrowHelper.ArgumentException("Cannot add this block as it as already attached to another container (block.Parent != null)");
var existingChild = children[index];
if (existingChild != null)
existingChild.Parent = null;
value.Parent = this;
children[index] = value;
}
}

View File

@@ -17,6 +17,11 @@ namespace Markdig.Syntax.Inlines
/// <seealso cref="Inline" />
public class ContainerInline : Inline, IEnumerable<Inline>
{
/// <summary>
/// Gets the parent block of this inline.
/// </summary>
public LeafBlock ParentBlock { get; internal set; }
/// <summary>
/// Gets the first child.
/// </summary>

View File

@@ -224,7 +224,7 @@ namespace Markdig.Syntax.Inlines
}
}
internal T FirstParentOfType<T>() where T : Inline
public T FirstParentOfType<T>() where T : Inline
{
var inline = this;
while (inline != null)

View File

@@ -16,6 +16,8 @@ namespace Markdig.Syntax
[DebuggerDisplay("{GetType().Name} Line: {Line}, {Lines}")]
public abstract class LeafBlock : Block
{
private ContainerInline inline;
/// <summary>
/// Initializes a new instance of the <see cref="LeafBlock"/> class.
/// </summary>
@@ -33,7 +35,30 @@ namespace Markdig.Syntax
/// <summary>
/// Gets or sets the inline syntax tree (may be null).
/// </summary>
public ContainerInline Inline { get; set; }
public ContainerInline Inline
{
get => inline;
set
{
if (value != null)
{
if (value.Parent != null)
ThrowHelper.ArgumentException("Cannot add this inline as it as already attached to another container (inline.Parent != null)");
if (value.ParentBlock != null)
ThrowHelper.ArgumentException("Cannot add this inline as it as already attached to another container (inline.ParentBlock != null)");
value.ParentBlock = this;
}
if (inline != null)
{
inline.ParentBlock = null;
}
inline = value;
}
}
/// <summary>
/// Gets or sets a value indicating whether <see cref="Lines"/> must be processed

7
src/Markdig/readme.md Normal file
View File

@@ -0,0 +1,7 @@
---
uid: Markdig
---
# Summary
Contains the top level classes for using Markdig. The entry user class is <xref:Markdig.Markdown>.

View File

@@ -110,20 +110,12 @@ namespace SpecFileGen
if (File.Exists(spec.OutputPath)) // If the source hasn't changed, don't bump the generated tag
{
string previousSource = File.ReadAllText(spec.OutputPath).Replace("\r\n", "\n", StringComparison.Ordinal);
int start = previousSource.IndexOf('\n', StringComparison.Ordinal) + 1;
int previousLength = previousSource.Length - start;
if (start != 0 && previousLength == source.Length)
if (previousSource == source)
{
if (previousSource.IndexOf(source, start, previousLength, StringComparison.Ordinal) == start)
{
// The source did not change
continue;
}
continue;
}
}
string generated = "// Generated: " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") + '\n';
File.WriteAllText(spec.OutputPath, generated + source);
File.WriteAllText(spec.OutputPath, source);
anyChanged = true;
}

View File

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

View File

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

7
src/global.json Normal file
View File

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

View File

@@ -5,13 +5,14 @@ VisualStudioVersion = 16.0.28407.52
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{061866E2-005C-4D13-A338-EA464BBEC60F}"
ProjectSection(SolutionItems) = preProject
..\changelog.md = ..\changelog.md
..\.github\workflows\ci.yml = ..\.github\workflows\ci.yml
..\license.txt = ..\license.txt
..\readme.md = ..\readme.md
..\.editorconfig = ..\.editorconfig
..\.gitattributes = ..\.gitattributes
..\.gitignore = ..\.gitignore
..\changelog.md = ..\changelog.md
..\.github\workflows\ci.yml = ..\.github\workflows\ci.yml
global.json = global.json
..\license.txt = ..\license.txt
..\readme.md = ..\readme.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Markdig", "Markdig\Markdig.csproj", "{8A58A7E2-627C-4F41-933F-5AC92ADFAB48}"

View File

@@ -3,4 +3,7 @@
This file is licensed under the BSD-Clause 2 license. &#xD;
See the license.txt file in the project root for more information.</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/NUnitProvider/SetCurrentDirectoryTo/@EntryValue">TestFolder</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/Environment/UnitTesting/NUnitProvider/SetCurrentDirectoryTo/@EntryValue">TestFolder</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Autolink/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Inlines/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Markdig/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

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