mirror of
https://github.com/xoofx/markdig.git
synced 2026-02-15 05:55:41 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5020fdd3b1 | ||
|
|
bd4ea56d2a | ||
|
|
fbc8a4116c | ||
|
|
9af318d334 | ||
|
|
88e561c3ae | ||
|
|
1ca82eb058 | ||
|
|
66007c6bbf | ||
|
|
14d4286fd7 | ||
|
|
58b1a48f5b | ||
|
|
5e1eaf8590 | ||
|
|
c946295d96 | ||
|
|
97cbf11f8b | ||
|
|
8d4394e7c6 | ||
|
|
fbdb8cf063 | ||
|
|
964538ec79 | ||
|
|
9a30883e2a | ||
|
|
6408705f82 | ||
|
|
523582e588 | ||
|
|
aaff022e7c | ||
|
|
37eb6aa529 | ||
|
|
9b7356b05e | ||
|
|
33d3bc1330 | ||
|
|
07a2980d5b | ||
|
|
2d8872f2a1 |
115
changelog.md
Normal file
115
changelog.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Changelog
|
||||
|
||||
## 0.14.8 (05 Dec 2017)
|
||||
- Fix potential StackOverflow exception when processing deep nested `|` delimiters (#179)
|
||||
## 0.14.7 (25 Nov 2017)
|
||||
- Fix autolink attached attributes not being displayed properly (#175)
|
||||
## 0.14.6 (21 Nov 2017)
|
||||
- Fix yaml frontmatter issue when ending with a empty line (#170)
|
||||
## 0.14.5 (18 Nov 2017)
|
||||
- Fix changelog link from nuget package
|
||||
## 0.14.4 (18 Nov 2017)
|
||||
- Add changelog.md
|
||||
- Fix bug when a thematic break is inside a fenced code block inside a pending list (#164)
|
||||
- Add support for GFM autolinks (#165, #169)
|
||||
- Better handle YAML frontmatter in case the opening `---` is never actually closed (#160)
|
||||
- Fix link conflict between a link to an image definition and heading auto-identifiers (#159)
|
||||
## 0.14.3
|
||||
- Make EmojiExtension.EnableSmiley public
|
||||
## 0.14.2
|
||||
- Fix issue with emphasis preceded/followed by an HTML entity (#157)
|
||||
- Add support for link reference definitions for Normalize renderer (#155)
|
||||
- Add option to disable smiley parsing in EmojiAndSmiley extension
|
||||
## 0.14.1
|
||||
- Fix crash in Markdown.Normalize to handle HtmlBlock correctly
|
||||
- Add better handling of bullet character for lists in Markdown.Normalize
|
||||
## 0.14.0
|
||||
- Add Markdown.ToPlainText, Add option HtmlRenderer.EnableHtmlForBlock.
|
||||
- Add Markdown.Normalize, to allow to normalize a markdown document. Add NormalizeRenderer, to render a MarkdownDocument back to markdown.
|
||||
## 0.13.4
|
||||
- Add support for single table header row without a table body rows (#141)
|
||||
- ADd support for `nomnoml` diagrams
|
||||
## 0.13.3
|
||||
- Add support for Pandoc YAML frontmatter (#138)
|
||||
## 0.13.2
|
||||
- Add support for UAP10.0 (#137)
|
||||
## 0.13.1
|
||||
- Fix indenting issue after a double digit list block using a tab (#134)
|
||||
## 0.13.0
|
||||
- Update to latest CommonMark specs 0.28
|
||||
## 0.12.3
|
||||
- Fix issue with HTML blocks for heading h2,h3,h4,h5,h6 that were not correctly identified as HTML blocks as per CommonMark spec
|
||||
## 0.12.2
|
||||
- Fix issue with generic attributes used just before a pipe table (issue #121)
|
||||
## 0.12.1
|
||||
- Fix issue with media links extension when a URL to video is used, an unexpected closing `</iframe>` was inserted (issue #119)
|
||||
## 0.12.0
|
||||
- Add new extension JiraLink support (thanks to @clarkd)
|
||||
- Fix issue in html attributes not parsing correctly properties (thanks to @meziantou)
|
||||
- Fix issues detected by an automatic static code analysis tool
|
||||
## 0.11.0
|
||||
- Fix issue with math extension and $$ block parsing not handling correctly beginning of a $$ as a inline math instead (issue #107)
|
||||
- Fix issue with custom attributes for emphasis
|
||||
- Add support for new special custom arrows emoji (`->` `<-` `<->` `<=` `=>` `<==>`)
|
||||
## 0.10.7
|
||||
- Fix issue when an url ends by a dot `.`
|
||||
## 0.10.6
|
||||
- Fix emphasis with HTML entities
|
||||
## 0.10.5
|
||||
- Several minor fixes
|
||||
## 0.10.4
|
||||
- Fix issue with autolinks
|
||||
- Normalize number of columns for tables
|
||||
## 0.10.3
|
||||
- Fix issue with pipetables shifting a cell to a new column (issue #73)
|
||||
## 0.10.2
|
||||
- Fix exception when trying to urlize an url with an unicode character outside the supported range by NormD (issue #75)
|
||||
## 0.10.1
|
||||
- Update to latest CommonMark specs
|
||||
- Fix source span for LinkReferenceDefinition
|
||||
## 0.10.0
|
||||
- Breaking change of the IMarkdownExtension to allow to receive the MarkdownPipeline for the renderers setup
|
||||
## 0.9.1
|
||||
- Fix regression bug with conflicts between autolink extension and html inline/regular links
|
||||
## 0.9.0
|
||||
- Add new Autolink extension
|
||||
## 0.8.5
|
||||
- Allow to force table column alignment to left
|
||||
## 0.8.4
|
||||
- Fix issue when calculating the span of an indented code block within a list. Make sure to include first whitespace on the line
|
||||
## 0.8.3
|
||||
- fix NullReferenceException with Gridtables extension when a single `+` is entered on a line
|
||||
## 0.8.2
|
||||
- fix potential cast exception with Abreviation extension and empty literals
|
||||
## 0.8.1
|
||||
- new extension to disable URI escaping for non-US-ASCII characters to workaround a bug in Edge/IE
|
||||
- Fix an issue with abbreviations with left/right multiple non-punctuation/space characters
|
||||
## 0.8.0
|
||||
- Update to latest CommonMark specs
|
||||
- Fix empty literal
|
||||
- Add YAML frontmatter extension
|
||||
## 0.7.5
|
||||
- several bug fixes (pipe tables, disable HTML, special attributes, inline maths, abbreviations...)
|
||||
- add support for rowspan in grid tables
|
||||
## 0.7.4
|
||||
- Fix bug with strong emphasis starting at the beginning of a line
|
||||
## 0.7.3
|
||||
- Fix threading issue with pipeline
|
||||
## 0.7.2
|
||||
- Fix rendering of table colspan with non english locale
|
||||
- Fix grid table colspan parsing
|
||||
- Add nofollow extension for links
|
||||
## 0.7.1
|
||||
- Fix issue in smarty pants which could lead to an InvalidCastException
|
||||
- Update parsers to latest CommonMark specs
|
||||
## 0.7.0
|
||||
- Update to latest NETStandard.Library 1.6.0
|
||||
- Fix issue with digits in auto-identifier extension
|
||||
- Fix incorrect start of span calculated for code indented blocks
|
||||
## 0.6.2
|
||||
- Handle latest CommonMark specs for corner cases for emphasis (See https://talk.commonmark.org/t/emphasis-strong-emphasis-corner-cases/2123/1 )
|
||||
## 0.6.1:
|
||||
- Fix issue with autoidentifier extension overriding manual HTML attributes id on headings
|
||||
## 0.6.0
|
||||
- Fix conflicts between PipeTables and SmartyPants extensions
|
||||
- Add SelfPipeline extension
|
||||
@@ -96,3 +96,14 @@ The text of the link can be changed:
|
||||
<p><a href="#this-is-a-heading">With a new text</a></p>
|
||||
<h1 id="this-is-a-heading">This is a heading</h1>
|
||||
````````````````````````````````
|
||||
|
||||
An autoidentifier should not conflict with an existing link:
|
||||
|
||||
```````````````````````````````` example
|
||||
![scenario image][scenario]
|
||||
## Scenario
|
||||
[scenario]: ./scenario.png
|
||||
.
|
||||
<p><img src="./scenario.png" alt="scenario image" /></p>
|
||||
<h2 id="scenario">Scenario</h2>
|
||||
````````````````````````````````
|
||||
|
||||
@@ -76,3 +76,67 @@ Check **http://www.a.com** or __http://www.b.com__
|
||||
.
|
||||
<p>Check <strong><a href="http://www.a.com">http://www.a.com</a></strong> or <strong><a href="http://www.b.com">http://www.b.com</a></strong></p>
|
||||
````````````````````````````````
|
||||
|
||||
### GFM Support
|
||||
|
||||
Extract from [GFM Autolinks extensions specs](https://github.github.com/gfm/#autolinks-extension-)
|
||||
|
||||
```````````````````````````````` example
|
||||
www.commonmark.org
|
||||
.
|
||||
<p><a href="http://www.commonmark.org">www.commonmark.org</a></p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
Visit www.commonmark.org/help for more information.
|
||||
.
|
||||
<p>Visit <a href="http://www.commonmark.org/help">www.commonmark.org/help</a> for more information.</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
Visit www.commonmark.org.
|
||||
|
||||
Visit www.commonmark.org/a.b.
|
||||
.
|
||||
<p>Visit <a href="http://www.commonmark.org">www.commonmark.org</a>.</p>
|
||||
<p>Visit <a href="http://www.commonmark.org/a.b">www.commonmark.org/a.b</a>.</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
www.google.com/search?q=Markup+(business)
|
||||
|
||||
(www.google.com/search?q=Markup+(business))
|
||||
.
|
||||
<p><a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a></p>
|
||||
<p>(<a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a>)</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
www.google.com/search?q=commonmark&hl=en
|
||||
|
||||
www.google.com/search?q=commonmark&hl;
|
||||
.
|
||||
<p><a href="http://www.google.com/search?q=commonmark&hl=en">www.google.com/search?q=commonmark&hl=en</a></p>
|
||||
<p><a href="http://www.google.com/search?q=commonmark">www.google.com/search?q=commonmark</a>&hl;</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
www.commonmark.org/he<lp
|
||||
.
|
||||
<p><a href="http://www.commonmark.org/he">www.commonmark.org/he</a><lp</p>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
http://commonmark.org
|
||||
|
||||
(Visit https://encrypted.google.com/search?q=Markup+(business))
|
||||
|
||||
Anonymous FTP is available at ftp://foo.bar.baz.
|
||||
.
|
||||
<p><a href="http://commonmark.org">http://commonmark.org</a></p>
|
||||
<p>(Visit <a href="https://encrypted.google.com/search?q=Markup+(business)">https://encrypted.google.com/search?q=Markup+(business)</a>)</p>
|
||||
<p>Anonymous FTP is available at <a href="ftp://foo.bar.baz">ftp://foo.bar.baz</a>.</p>
|
||||
````````````````````````````````
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Markdig.Tests
|
||||
@@ -20328,6 +20328,29 @@ namespace Markdig.Tests
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 10, "Extensions Heading Auto Identifiers");
|
||||
TestParser.TestSpec("[With a new text][This is a heading]\n# This is a heading", "<p><a href=\"#this-is-a-heading\">With a new text</a></p>\n<h1 id=\"this-is-a-heading\">This is a heading</h1>", "autoidentifiers|advanced");
|
||||
}
|
||||
}
|
||||
// An autoidentifier should not conflict with an existing link:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsHeadingAutoIdentifiers
|
||||
{
|
||||
[Test]
|
||||
public void Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions Heading Auto Identifiers
|
||||
//
|
||||
// The following CommonMark:
|
||||
// ![scenario image][scenario]
|
||||
// ## Scenario
|
||||
// [scenario]: ./scenario.png
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><img src="./scenario.png" alt="scenario image" /></p>
|
||||
// <h2 id="scenario">Scenario</h2>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 11, "Extensions Heading Auto Identifiers");
|
||||
TestParser.TestSpec("![scenario image][scenario]\n## Scenario\n[scenario]: ./scenario.png", "<p><img src=\"./scenario.png\" alt=\"scenario image\" /></p>\n<h2 id=\"scenario\">Scenario</h2>", "autoidentifiers|advanced");
|
||||
}
|
||||
}
|
||||
// # Extensions
|
||||
//
|
||||
@@ -20607,6 +20630,7 @@ namespace Markdig.Tests
|
||||
// The following CommonMark:
|
||||
// ---
|
||||
// this: is a frontmatter
|
||||
//
|
||||
// ...
|
||||
// This is a text
|
||||
//
|
||||
@@ -20614,10 +20638,10 @@ namespace Markdig.Tests
|
||||
// <p>This is a text</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 4, "Extensions YAML frontmatter discard");
|
||||
TestParser.TestSpec("---\nthis: is a frontmatter\n...\nThis is a text", "<p>This is a text</p>", "yaml");
|
||||
TestParser.TestSpec("---\nthis: is a frontmatter\n\n...\nThis is a text", "<p>This is a text</p>", "yaml");
|
||||
}
|
||||
}
|
||||
// It expects exactly three dots `...`:
|
||||
// If the end front matter marker (`...` or `---`) is not present, it will render the `---` has a `<hr>`:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsYAMLfrontmatterdiscard
|
||||
{
|
||||
@@ -20630,17 +20654,18 @@ namespace Markdig.Tests
|
||||
// The following CommonMark:
|
||||
// ---
|
||||
// this: is a frontmatter
|
||||
// ....
|
||||
// This is a text
|
||||
//
|
||||
// Should be rendered as:
|
||||
//
|
||||
// <hr />
|
||||
// <p>this: is a frontmatter
|
||||
// This is a text</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 5, "Extensions YAML frontmatter discard");
|
||||
TestParser.TestSpec("---\nthis: is a frontmatter\n....\nThis is a text", "", "yaml");
|
||||
TestParser.TestSpec("---\nthis: is a frontmatter\nThis is a text", "<hr />\n<p>this: is a frontmatter\nThis is a text</p>", "yaml");
|
||||
}
|
||||
}
|
||||
// Front matter ends with the first line containing three dots `...` or three dashes `...`:
|
||||
// It expects exactly three dots `...`:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsYAMLfrontmatterdiscard
|
||||
{
|
||||
@@ -20654,6 +20679,32 @@ namespace Markdig.Tests
|
||||
// ---
|
||||
// this: is a frontmatter
|
||||
// ....
|
||||
// This is a text
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <hr />
|
||||
// <p>this: is a frontmatter
|
||||
// ....
|
||||
// This is a text</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 6, "Extensions YAML frontmatter discard");
|
||||
TestParser.TestSpec("---\nthis: is a frontmatter\n....\nThis is a text", "<hr />\n<p>this: is a frontmatter\n....\nThis is a text</p>", "yaml");
|
||||
}
|
||||
}
|
||||
// Front matter ends with the first line containing three dots `...` or three dashes `...`:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsYAMLfrontmatterdiscard
|
||||
{
|
||||
[Test]
|
||||
public void Example007()
|
||||
{
|
||||
// Example 7
|
||||
// Section: Extensions YAML frontmatter discard
|
||||
//
|
||||
// The following CommonMark:
|
||||
// ---
|
||||
// this: is a frontmatter
|
||||
// ....
|
||||
//
|
||||
// Hello
|
||||
// ---
|
||||
@@ -20662,7 +20713,7 @@ namespace Markdig.Tests
|
||||
// Should be rendered as:
|
||||
// <p>This is a text</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 6, "Extensions YAML frontmatter discard");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 7, "Extensions YAML frontmatter discard");
|
||||
TestParser.TestSpec("---\nthis: is a frontmatter\n....\n\nHello\n---\nThis is a text", "<p>This is a text</p>", "yaml");
|
||||
}
|
||||
}
|
||||
@@ -20671,9 +20722,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsYAMLfrontmatterdiscard
|
||||
{
|
||||
[Test]
|
||||
public void Example007()
|
||||
public void Example008()
|
||||
{
|
||||
// Example 7
|
||||
// Example 8
|
||||
// Section: Extensions YAML frontmatter discard
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -20685,7 +20736,7 @@ namespace Markdig.Tests
|
||||
// Should be rendered as:
|
||||
// <p>This is a text</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 7, "Extensions YAML frontmatter discard");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 8, "Extensions YAML frontmatter discard");
|
||||
TestParser.TestSpec("--- \nthis: is a frontmatter\n...\nThis is a text", "<p>This is a text</p>", "yaml");
|
||||
}
|
||||
}
|
||||
@@ -20694,9 +20745,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsYAMLfrontmatterdiscard
|
||||
{
|
||||
[Test]
|
||||
public void Example008()
|
||||
public void Example009()
|
||||
{
|
||||
// Example 8
|
||||
// Example 9
|
||||
// Section: Extensions YAML frontmatter discard
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -20708,7 +20759,7 @@ namespace Markdig.Tests
|
||||
// Should be rendered as:
|
||||
// <p>This is a text</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 8, "Extensions YAML frontmatter discard");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 9, "Extensions YAML frontmatter discard");
|
||||
TestParser.TestSpec("---\nthis: is a frontmatter\n... \nThis is a text", "<p>This is a text</p>", "yaml");
|
||||
}
|
||||
}
|
||||
@@ -20874,6 +20925,157 @@ namespace Markdig.Tests
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 7, "Extensions AutoLinks");
|
||||
TestParser.TestSpec("Check **http://www.a.com** or __http://www.b.com__", "<p>Check <strong><a href=\"http://www.a.com\">http://www.a.com</a></strong> or <strong><a href=\"http://www.b.com\">http://www.b.com</a></strong></p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
// ### GFM Support
|
||||
//
|
||||
// Extract from [GFM Autolinks extensions specs](https://github.github.com/gfm/#autolinks-extension-)
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
[Test]
|
||||
public void Example008()
|
||||
{
|
||||
// Example 8
|
||||
// Section: Extensions AutoLinks GFM Support
|
||||
//
|
||||
// The following CommonMark:
|
||||
// www.commonmark.org
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.commonmark.org">www.commonmark.org</a></p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 8, "Extensions AutoLinks GFM Support");
|
||||
TestParser.TestSpec("www.commonmark.org", "<p><a href=\"http://www.commonmark.org\">www.commonmark.org</a></p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
[Test]
|
||||
public void Example009()
|
||||
{
|
||||
// Example 9
|
||||
// Section: Extensions AutoLinks GFM Support
|
||||
//
|
||||
// The following CommonMark:
|
||||
// Visit www.commonmark.org/help for more information.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Visit <a href="http://www.commonmark.org/help">www.commonmark.org/help</a> for more information.</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 9, "Extensions AutoLinks GFM Support");
|
||||
TestParser.TestSpec("Visit www.commonmark.org/help for more information.", "<p>Visit <a href=\"http://www.commonmark.org/help\">www.commonmark.org/help</a> for more information.</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
[Test]
|
||||
public void Example010()
|
||||
{
|
||||
// Example 10
|
||||
// Section: Extensions AutoLinks GFM Support
|
||||
//
|
||||
// The following CommonMark:
|
||||
// Visit www.commonmark.org.
|
||||
//
|
||||
// Visit www.commonmark.org/a.b.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>Visit <a href="http://www.commonmark.org">www.commonmark.org</a>.</p>
|
||||
// <p>Visit <a href="http://www.commonmark.org/a.b">www.commonmark.org/a.b</a>.</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 10, "Extensions AutoLinks GFM Support");
|
||||
TestParser.TestSpec("Visit www.commonmark.org.\n\nVisit www.commonmark.org/a.b.", "<p>Visit <a href=\"http://www.commonmark.org\">www.commonmark.org</a>.</p>\n<p>Visit <a href=\"http://www.commonmark.org/a.b\">www.commonmark.org/a.b</a>.</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
[Test]
|
||||
public void Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions AutoLinks GFM Support
|
||||
//
|
||||
// The following CommonMark:
|
||||
// www.google.com/search?q=Markup+(business)
|
||||
//
|
||||
// (www.google.com/search?q=Markup+(business))
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a></p>
|
||||
// <p>(<a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a>)</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 11, "Extensions AutoLinks GFM Support");
|
||||
TestParser.TestSpec("www.google.com/search?q=Markup+(business)\n\n(www.google.com/search?q=Markup+(business))", "<p><a href=\"http://www.google.com/search?q=Markup+(business)\">www.google.com/search?q=Markup+(business)</a></p>\n<p>(<a href=\"http://www.google.com/search?q=Markup+(business)\">www.google.com/search?q=Markup+(business)</a>)</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
[Test]
|
||||
public void Example012()
|
||||
{
|
||||
// Example 12
|
||||
// Section: Extensions AutoLinks GFM Support
|
||||
//
|
||||
// The following CommonMark:
|
||||
// www.google.com/search?q=commonmark&hl=en
|
||||
//
|
||||
// www.google.com/search?q=commonmark&hl;
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.google.com/search?q=commonmark&hl=en">www.google.com/search?q=commonmark&hl=en</a></p>
|
||||
// <p><a href="http://www.google.com/search?q=commonmark">www.google.com/search?q=commonmark</a>&hl;</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 12, "Extensions AutoLinks GFM Support");
|
||||
TestParser.TestSpec("www.google.com/search?q=commonmark&hl=en\n\nwww.google.com/search?q=commonmark&hl;", "<p><a href=\"http://www.google.com/search?q=commonmark&hl=en\">www.google.com/search?q=commonmark&hl=en</a></p>\n<p><a href=\"http://www.google.com/search?q=commonmark\">www.google.com/search?q=commonmark</a>&hl;</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
[Test]
|
||||
public void Example013()
|
||||
{
|
||||
// Example 13
|
||||
// Section: Extensions AutoLinks GFM Support
|
||||
//
|
||||
// The following CommonMark:
|
||||
// www.commonmark.org/he<lp
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://www.commonmark.org/he">www.commonmark.org/he</a><lp</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 13, "Extensions AutoLinks GFM Support");
|
||||
TestParser.TestSpec("www.commonmark.org/he<lp", "<p><a href=\"http://www.commonmark.org/he\">www.commonmark.org/he</a><lp</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinksGFMSupport
|
||||
{
|
||||
[Test]
|
||||
public void Example014()
|
||||
{
|
||||
// Example 14
|
||||
// Section: Extensions AutoLinks GFM Support
|
||||
//
|
||||
// The following CommonMark:
|
||||
// http://commonmark.org
|
||||
//
|
||||
// (Visit https://encrypted.google.com/search?q=Markup+(business))
|
||||
//
|
||||
// Anonymous FTP is available at ftp://foo.bar.baz.
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p><a href="http://commonmark.org">http://commonmark.org</a></p>
|
||||
// <p>(Visit <a href="https://encrypted.google.com/search?q=Markup+(business)">https://encrypted.google.com/search?q=Markup+(business)</a>)</p>
|
||||
// <p>Anonymous FTP is available at <a href="ftp://foo.bar.baz">ftp://foo.bar.baz</a>.</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 14, "Extensions AutoLinks GFM Support");
|
||||
TestParser.TestSpec("http://commonmark.org\n\n(Visit https://encrypted.google.com/search?q=Markup+(business))\n\nAnonymous FTP is available at ftp://foo.bar.baz.", "<p><a href=\"http://commonmark.org\">http://commonmark.org</a></p>\n<p>(Visit <a href=\"https://encrypted.google.com/search?q=Markup+(business)\">https://encrypted.google.com/search?q=Markup+(business)</a>)</p>\n<p>Anonymous FTP is available at <a href=\"ftp://foo.bar.baz\">ftp://foo.bar.baz</a>.</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
// ## Jira Links
|
||||
//
|
||||
|
||||
@@ -47,12 +47,25 @@ It can end with three dots `...`:
|
||||
```````````````````````````````` example
|
||||
---
|
||||
this: is a frontmatter
|
||||
|
||||
...
|
||||
This is a text
|
||||
.
|
||||
<p>This is a text</p>
|
||||
````````````````````````````````
|
||||
|
||||
If the end front matter marker (`...` or `---`) is not present, it will render the `---` has a `<hr>`:
|
||||
|
||||
```````````````````````````````` example
|
||||
---
|
||||
this: is a frontmatter
|
||||
This is a text
|
||||
.
|
||||
<hr />
|
||||
<p>this: is a frontmatter
|
||||
This is a text</p>
|
||||
````````````````````````````````
|
||||
|
||||
It expects exactly three dots `...`:
|
||||
|
||||
```````````````````````````````` example
|
||||
@@ -61,6 +74,10 @@ this: is a frontmatter
|
||||
....
|
||||
This is a text
|
||||
.
|
||||
<hr />
|
||||
<p>this: is a frontmatter
|
||||
....
|
||||
This is a text</p>
|
||||
````````````````````````````````
|
||||
|
||||
Front matter ends with the first line containing three dots `...` or three dashes `...`:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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.
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Markdig.Tests
|
||||
{
|
||||
var text = new StringSlice(uri);
|
||||
string link;
|
||||
Assert.True(LinkHelper.TryParseUrl(ref text, out link));
|
||||
Assert.True(LinkHelper.TryParseUrl(ref text, out link, true));
|
||||
Assert.AreEqual("http://google.com", link);
|
||||
Assert.AreEqual('.', text.CurrentChar);
|
||||
}
|
||||
|
||||
@@ -396,6 +396,21 @@ This is a last line";
|
||||
AssertNormalizeNoTrim(input);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TaskLists()
|
||||
{
|
||||
AssertNormalizeNoTrim("- [X] This is done");
|
||||
AssertNormalizeNoTrim("- [x] This is done",
|
||||
"- [X] This is done");
|
||||
AssertNormalizeNoTrim("- [ ] This is not done");
|
||||
|
||||
// ignore
|
||||
AssertNormalizeNoTrim("[x] This is not a task list");
|
||||
AssertNormalizeNoTrim("[ ] This is not a task list");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void AssertSyntax(string expected, MarkdownObject syntax)
|
||||
{
|
||||
var writer = new StringWriter();
|
||||
@@ -425,7 +440,11 @@ This is a last line";
|
||||
input = NormText(input, trim);
|
||||
expected = NormText(expected, trim);
|
||||
|
||||
var result = Markdown.Normalize(input, options);
|
||||
var pipeline = new MarkdownPipelineBuilder()
|
||||
.UseTaskLists()
|
||||
.Build();
|
||||
|
||||
var result = Markdown.Normalize(input, options, pipeline: pipeline);
|
||||
result = NormText(result, trim);
|
||||
|
||||
Console.WriteLine("```````````````````Source");
|
||||
|
||||
@@ -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 System;
|
||||
using System.Collections.Generic;
|
||||
@@ -19,6 +19,25 @@ namespace Markdig.Tests
|
||||
TestSpec(markdownText, "<p><em>Unlimited-Fun®</em>®</p>");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestThematicInsideCodeBlockInsideList()
|
||||
{
|
||||
var input = @"1. In the :
|
||||
|
||||
```
|
||||
Id DisplayName Description
|
||||
-- ----------- -----------
|
||||
62375ab9-6b52-47ed-826b-58e47e0e304b Group.Unified ...
|
||||
```";
|
||||
TestSpec(input, @"<ol>
|
||||
<li><p>In the :</p>
|
||||
<pre><code>Id DisplayName Description
|
||||
-- ----------- -----------
|
||||
62375ab9-6b52-47ed-826b-58e47e0e304b Group.Unified ...
|
||||
</code></pre></li>
|
||||
</ol>");
|
||||
}
|
||||
|
||||
public static void TestSpec(string inputText, string expectedOutputText, string extensions = null)
|
||||
{
|
||||
foreach (var pipeline in GetPipeline(extensions))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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;
|
||||
@@ -12,6 +12,14 @@ namespace Markdig.Tests
|
||||
[TestFixture]
|
||||
public class TestPlayParser
|
||||
{
|
||||
[Test]
|
||||
public void TestLink()
|
||||
{
|
||||
var doc = Markdown.Parse("There is a ");
|
||||
var link = doc.Descendants<ParagraphBlock>().SelectMany(x => x.Inline.Descendants<LinkInline>()).FirstOrDefault(l => l.IsImage);
|
||||
Assert.AreEqual("/yoyo", link?.Url);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestListBug2()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
@@ -6,6 +6,13 @@ namespace Markdig.WebApp
|
||||
{
|
||||
public class ApiController : Controller
|
||||
{
|
||||
[HttpGet()]
|
||||
[Route("")]
|
||||
public string Empty()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// GET api/to_html?text=xxx&extensions=advanced
|
||||
[Route("api/to_html")]
|
||||
[HttpGet()]
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider",
|
||||
"Version": "8.9.809.2",
|
||||
"GettingStartedDocument": {
|
||||
"Uri": "https://go.microsoft.com/fwlink/?LinkID=798432"
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp1.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<AssemblyName>Markdig.WebApp</AssemblyName>
|
||||
<OutputType>Exe</OutputType>
|
||||
<PackageId>Markdig.WebApp</PackageId>
|
||||
<RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
|
||||
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;dnxcore50;portable-net45+win8</PackageTargetFallback>
|
||||
<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>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -21,16 +22,20 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<WCFMetadata Include="Connected Services" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -13,6 +13,7 @@ namespace Markdig.WebApp
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseApplicationInsights()
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@@ -46,10 +46,6 @@ namespace Markdig.WebApp
|
||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
loggerFactory.AddDebug();
|
||||
|
||||
app.UseApplicationInsightsRequestTelemetry();
|
||||
|
||||
app.UseApplicationInsightsExceptionTelemetry();
|
||||
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
@@ -6,5 +6,8 @@
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
},
|
||||
"ApplicationInsights": {
|
||||
"InstrumentationKey": "5d12f113-76b2-41fe-a35a-db454b104bf9"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Markdig.Helpers;
|
||||
@@ -89,13 +90,41 @@ namespace Markdig.Extensions.AutoIdentifiers
|
||||
Heading = headingBlock,
|
||||
CreateLinkInline = CreateLinkInlineForHeading
|
||||
};
|
||||
processor.Document.SetLinkReferenceDefinition(text, linkRef);
|
||||
|
||||
var doc = processor.Document;
|
||||
var dictionary = doc.GetData(this) as Dictionary<string, HeadingLinkReferenceDefinition>;
|
||||
if (dictionary == null)
|
||||
{
|
||||
dictionary = new Dictionary<string, HeadingLinkReferenceDefinition>();
|
||||
doc.SetData(this, dictionary);
|
||||
doc.ProcessInlinesBegin += DocumentOnProcessInlinesBegin;
|
||||
}
|
||||
dictionary[text] = linkRef;
|
||||
}
|
||||
|
||||
// Then we register after inline have been processed to actually generate the proper #id
|
||||
headingBlock.ProcessInlinesEnd += HeadingBlock_ProcessInlinesEnd;
|
||||
}
|
||||
|
||||
private void DocumentOnProcessInlinesBegin(InlineProcessor processor, Inline inline)
|
||||
{
|
||||
var doc = processor.Document;
|
||||
doc.ProcessInlinesBegin -= DocumentOnProcessInlinesBegin;
|
||||
var dictionary = (Dictionary<string, HeadingLinkReferenceDefinition>)doc.GetData(this);
|
||||
foreach (var keyPair in dictionary)
|
||||
{
|
||||
// Here we make sure that auto-identifiers will not override an existing link definition
|
||||
// defined in the document
|
||||
// If it is the case, we skip the auto identifier for the Heading
|
||||
if (!doc.TryGetLinkReferenceDefinition(keyPair.Key, out var linkDef))
|
||||
{
|
||||
doc.SetLinkReferenceDefinition(keyPair.Key, keyPair.Value);
|
||||
}
|
||||
}
|
||||
// Once we are done, we don't need to keep the intermediate dictionary arround
|
||||
doc.RemoveData(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback when there is a reference to found to a heading.
|
||||
/// Note that reference are only working if they are declared after.
|
||||
@@ -144,13 +173,15 @@ namespace Markdig.Extensions.AutoIdentifiers
|
||||
var headingText = headingWriter.ToString();
|
||||
headingWriter.GetStringBuilder().Length = 0;
|
||||
|
||||
// TODO: Should we have a struct with more configure optionss for LinkHelper.Urilize?
|
||||
headingText = LinkHelper.Urilize(headingText,
|
||||
(options & AutoIdentifierOptions.AllowOnlyAscii) != 0,
|
||||
(options & AutoIdentifierOptions.KeepOpeningDigits) != 0,
|
||||
(options & AutoIdentifierOptions.DiscardDots) != 0);
|
||||
// Urilize the link
|
||||
headingText = (options & AutoIdentifierOptions.GitHub) != 0
|
||||
? LinkHelper.UrilizeAsGfm(headingText)
|
||||
: LinkHelper.Urilize(headingText, (options & AutoIdentifierOptions.AllowOnlyAscii) != 0);
|
||||
|
||||
// If the heading is empty, use the word "section" instead
|
||||
var baseHeadingId = string.IsNullOrEmpty(headingText) ? "section" : headingText;
|
||||
|
||||
// Add a trailing -1, -2, -3...etc. in case of collision
|
||||
int index = 0;
|
||||
var headingId = baseHeadingId;
|
||||
var headingBuffer = StringBuilderCache.Local();
|
||||
|
||||
@@ -21,11 +21,6 @@ namespace Markdig.Extensions.AutoIdentifiers
|
||||
/// </summary>
|
||||
Default = AutoLink | AllowOnlyAscii,
|
||||
|
||||
/// <summary>
|
||||
/// Renders auto identifiers like GitHub.
|
||||
/// </summary>
|
||||
GitHub = Default | KeepOpeningDigits | DiscardDots,
|
||||
|
||||
/// <summary>
|
||||
/// Allows to link to a header by using the same text as the header for the link label. Default is <c>true</c>
|
||||
/// </summary>
|
||||
@@ -37,13 +32,8 @@ namespace Markdig.Extensions.AutoIdentifiers
|
||||
AllowOnlyAscii = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Allows to keep digits starting a heading (by default, it keeps only characters starting from the first letter)
|
||||
/// Renders auto identifiers like GitHub.
|
||||
/// </summary>
|
||||
KeepOpeningDigits = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Discard dots when computing an identifier.
|
||||
/// </summary>
|
||||
DiscardDots = 8
|
||||
GitHub = 4,
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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.
|
||||
|
||||
@@ -30,11 +30,18 @@ namespace Markdig.Extensions.AutoLinks
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static bool IsValidPreviousCharacter(char c)
|
||||
{
|
||||
// All such recognized autolinks can only come at the beginning of a line, after whitespace, or any of the delimiting characters *, _, ~, and (.
|
||||
return c.IsWhiteSpaceOrZero() || c == '*' || c == '_' || c == '~' || c == '(';
|
||||
}
|
||||
|
||||
public override bool Match(InlineProcessor processor, ref StringSlice slice)
|
||||
{
|
||||
// Previous char must be a whitespace or a punctuation
|
||||
var previousChar = slice.PeekCharExtra(-1);
|
||||
if (!previousChar.IsAsciiPunctuation() && !previousChar.IsWhiteSpaceOrZero())
|
||||
if (!IsValidPreviousCharacter(previousChar))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -72,7 +79,7 @@ namespace Markdig.Extensions.AutoLinks
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if (!slice.MatchLowercase("ww.", 1) || previousChar == '/') // We won't match http:/www. or /www.xxx
|
||||
if (!slice.MatchLowercase("ww.", 1)) // We won't match http:/www. or /www.xxx
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -81,7 +88,7 @@ namespace Markdig.Extensions.AutoLinks
|
||||
|
||||
// Parse URL
|
||||
string link;
|
||||
if (!LinkHelper.TryParseUrl(ref slice, out link))
|
||||
if (!LinkHelper.TryParseUrl(ref slice, out link, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,19 +12,19 @@ namespace Markdig.Extensions.Emoji
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class EmojiExtension : IMarkdownExtension
|
||||
{
|
||||
private readonly bool _enableSmiley;
|
||||
|
||||
public EmojiExtension(bool enableSmiley = true)
|
||||
{
|
||||
_enableSmiley = enableSmiley;
|
||||
EnableSmiley = enableSmiley;
|
||||
}
|
||||
|
||||
public bool EnableSmiley { get; set; }
|
||||
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.InlineParsers.Contains<EmojiParser>())
|
||||
{
|
||||
// Insert the parser before any other parsers
|
||||
pipeline.InlineParsers.Insert(0, new EmojiParser(_enableSmiley));
|
||||
pipeline.InlineParsers.Insert(0, new EmojiParser(EnableSmiley));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using Markdig.Renderers.Normalize;
|
||||
|
||||
namespace Markdig.Extensions.TaskLists
|
||||
{
|
||||
public class NormalizeTaskListRenderer : NormalizeObjectRenderer<TaskList>
|
||||
{
|
||||
protected override void Write(NormalizeRenderer renderer, TaskList obj)
|
||||
{
|
||||
renderer.Write("[");
|
||||
renderer.Write(obj.Checked ? "X" : " ");
|
||||
renderer.Write("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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 Markdig.Parsers.Inlines;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Renderers.Normalize;
|
||||
|
||||
namespace Markdig.Extensions.TaskLists
|
||||
{
|
||||
@@ -28,6 +29,12 @@ namespace Markdig.Extensions.TaskLists
|
||||
{
|
||||
htmlRenderer.ObjectRenderers.AddIfNotAlready<HtmlTaskListRenderer>();
|
||||
}
|
||||
|
||||
var normalizeRenderer = renderer as NormalizeRenderer;
|
||||
if (normalizeRenderer != null)
|
||||
{
|
||||
normalizeRenderer.ObjectRenderers.AddIfNotAlready<NormalizeTaskListRenderer>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,17 +67,55 @@ namespace Markdig.Extensions.Yaml
|
||||
// this is a YAML front matter blcok
|
||||
if (count == 3 && (c == '\0' || c.IsWhitespace()) && line.TrimEnd())
|
||||
{
|
||||
// Create a front matter block
|
||||
var block = this.CreateFrontMatterBlock(processor);
|
||||
block.Column = processor.Column;
|
||||
block.Span.Start = 0;
|
||||
block.Span.End = line.Start;
|
||||
bool hasFullYamlFrontMatter = false;
|
||||
// We make sure that there is a closing frontmatter somewhere in the document
|
||||
// so here we work on the full document instead of just the line
|
||||
var fullLine = new StringSlice(line.Text, line.Start, line.Text.Length - 1);
|
||||
c = fullLine.CurrentChar;
|
||||
while (c != '\0')
|
||||
{
|
||||
c = fullLine.NextChar();
|
||||
if (c == '\n' || c == '\r')
|
||||
{
|
||||
var nc = fullLine.PeekChar();
|
||||
if (c == '\r' && nc == '\n')
|
||||
{
|
||||
c = fullLine.NextChar();
|
||||
}
|
||||
nc = fullLine.PeekChar();
|
||||
if (nc == '-')
|
||||
{
|
||||
if (fullLine.NextChar() == '-' && fullLine.NextChar() == '-' && fullLine.NextChar() == '-' && (fullLine.NextChar() == '\0' || fullLine.SkipSpacesToEndOfLineOrEndOfDocument()))
|
||||
{
|
||||
hasFullYamlFrontMatter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (nc == '.')
|
||||
{
|
||||
if (fullLine.NextChar() == '.' && fullLine.NextChar() == '.' && fullLine.NextChar() == '.' && (fullLine.NextChar() == '\0' || fullLine.SkipSpacesToEndOfLineOrEndOfDocument()))
|
||||
{
|
||||
hasFullYamlFrontMatter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store the number of matched string into the context
|
||||
processor.NewBlocks.Push(block);
|
||||
if (hasFullYamlFrontMatter)
|
||||
{
|
||||
// Create a front matter block
|
||||
var block = this.CreateFrontMatterBlock(processor);
|
||||
block.Column = processor.Column;
|
||||
block.Span.Start = 0;
|
||||
block.Span.End = line.Start;
|
||||
|
||||
// Discard the current line as it is already parsed
|
||||
return BlockState.ContinueDiscard;
|
||||
// Store the number of matched string into the context
|
||||
processor.NewBlocks.Push(block);
|
||||
|
||||
// Discard the current line as it is already parsed
|
||||
return BlockState.ContinueDiscard;
|
||||
}
|
||||
}
|
||||
|
||||
return BlockState.None;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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.
|
||||
|
||||
@@ -472,10 +472,10 @@ namespace Markdig.Helpers
|
||||
}
|
||||
else if (c == '&')
|
||||
{
|
||||
string namedEntity;
|
||||
int entityNameStart;
|
||||
int entityNameLength;
|
||||
int numericEntity;
|
||||
var match = ScanEntity(text, searchPos, text.Length - searchPos, out namedEntity,
|
||||
out numericEntity);
|
||||
var match = ScanEntity(new StringSlice(text, searchPos, text.Length - 1), out numericEntity, out entityNameStart, out entityNameLength);
|
||||
if (match == 0)
|
||||
{
|
||||
searchPos++;
|
||||
@@ -484,9 +484,10 @@ namespace Markdig.Helpers
|
||||
{
|
||||
searchPos += match;
|
||||
|
||||
if (namedEntity != null)
|
||||
if (entityNameLength > 0)
|
||||
{
|
||||
var decoded = EntityHelper.DecodeEntity(namedEntity);
|
||||
var namedEntity = new StringSlice(text, entityNameStart, entityNameStart + entityNameLength - 1);
|
||||
var decoded = EntityHelper.DecodeEntity(namedEntity.ToString());
|
||||
if (decoded != null)
|
||||
{
|
||||
sb.Append(text, lastPos, searchPos - match - lastPos);
|
||||
@@ -533,7 +534,7 @@ namespace Markdig.Helpers
|
||||
/// Scans an entity.
|
||||
/// Returns number of chars matched.
|
||||
/// </summary>
|
||||
public static int ScanEntity(string s, int pos, int length, out string namedEntity, out int numericEntity)
|
||||
public static int ScanEntity<T>(T slice, out int numericEntity, out int namedEntityStart, out int namedEntityLength) where T : ICharIterator
|
||||
{
|
||||
// Credits: code from CommonMark.NET
|
||||
// Copyright (c) 2014, Kārlis Gaņģis All rights reserved.
|
||||
@@ -545,29 +546,29 @@ namespace Markdig.Helpers
|
||||
.? { return 0; }
|
||||
*/
|
||||
|
||||
var lastPos = pos + length;
|
||||
|
||||
namedEntity = null;
|
||||
numericEntity = 0;
|
||||
namedEntityStart = 0;
|
||||
namedEntityLength = 0;
|
||||
|
||||
if (pos + 3 >= lastPos)
|
||||
return 0;
|
||||
|
||||
if (s[pos] != '&')
|
||||
return 0;
|
||||
|
||||
char c;
|
||||
int i;
|
||||
int counter = 0;
|
||||
if (s[pos + 1] == '#')
|
||||
if (slice.CurrentChar != '&' || slice.PeekChar(3) == '\0')
|
||||
{
|
||||
c = s[pos + 2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
var start = slice.Start;
|
||||
char c = slice.NextChar();
|
||||
int counter = 0;
|
||||
|
||||
if (c == '#')
|
||||
{
|
||||
c = slice.PeekChar();
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
c = slice.NextChar(); // skip #
|
||||
// expect 1-8 hex digits starting from pos+3
|
||||
for (i = pos + 3; i < lastPos; i++)
|
||||
while (c != '\0')
|
||||
{
|
||||
c = s[i];
|
||||
c = slice.NextChar();
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
@@ -588,7 +589,7 @@ namespace Markdig.Helpers
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
return counter == 0 ? 0 : slice.Start - start + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -596,9 +597,10 @@ namespace Markdig.Helpers
|
||||
else
|
||||
{
|
||||
// expect 1-8 digits starting from pos+2
|
||||
for (i = pos + 2; i < lastPos; i++)
|
||||
while (c != '\0')
|
||||
{
|
||||
c = s[i];
|
||||
c = slice.NextChar();
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
if (++counter == 9) return 0;
|
||||
@@ -607,7 +609,7 @@ namespace Markdig.Helpers
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
return counter == 0 ? 0 : slice.Start - start + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -616,25 +618,26 @@ namespace Markdig.Helpers
|
||||
else
|
||||
{
|
||||
// expect a letter and 1-31 letters or digits
|
||||
c = s[pos + 1];
|
||||
if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')))
|
||||
return 0;
|
||||
|
||||
for (i = pos + 2; i < lastPos; i++)
|
||||
namedEntityStart = slice.Start;
|
||||
namedEntityLength++;
|
||||
|
||||
while (c != '\0')
|
||||
{
|
||||
c = s[i];
|
||||
c = slice.NextChar();
|
||||
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
|
||||
{
|
||||
if (++counter == 32)
|
||||
return 0;
|
||||
|
||||
namedEntityLength++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ';')
|
||||
{
|
||||
namedEntity = s.Substring(pos + 1, counter + 1);
|
||||
return counter == 0 ? 0 : i - pos + 1;
|
||||
return counter == 0 ? 0 : slice.Start - start + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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.
|
||||
|
||||
@@ -34,8 +34,9 @@ namespace Markdig.Helpers
|
||||
/// <summary>
|
||||
/// Peeks at the next character, without incrementing the <see cref="Start"/> position.
|
||||
/// </summary>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns>The next character. `\0` is end of the iteration.</returns>
|
||||
char PeekChar();
|
||||
char PeekChar(int offset = 1);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is empty.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using Markdig.Parsers.Inlines;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Markdig.Helpers
|
||||
@@ -18,7 +19,7 @@ namespace Markdig.Helpers
|
||||
return TryParseAutolink(ref text, out link, out isEmail);
|
||||
}
|
||||
|
||||
public static string Urilize(string headingText, bool allowOnlyAscii, bool keepOpeningDigits = false, bool discardDots = false)
|
||||
public static string Urilize(string headingText, bool allowOnlyAscii, bool keepOpeningDigits = false)
|
||||
{
|
||||
var headingBuffer = StringBuilderCache.Local();
|
||||
bool hasLetter = keepOpeningDigits && headingText.Length > 0 && char.IsLetterOrDigit(headingText[0]);
|
||||
@@ -47,7 +48,7 @@ namespace Markdig.Helpers
|
||||
}
|
||||
else if (hasLetter)
|
||||
{
|
||||
if (IsReservedPunctuation(c, discardDots))
|
||||
if (IsReservedPunctuation(c))
|
||||
{
|
||||
if (previousIsSpace)
|
||||
{
|
||||
@@ -67,7 +68,7 @@ namespace Markdig.Helpers
|
||||
else if (!previousIsSpace && c.IsWhitespace())
|
||||
{
|
||||
var pc = headingBuffer[headingBuffer.Length - 1];
|
||||
if (!IsReservedPunctuation(pc, discardDots))
|
||||
if (!IsReservedPunctuation(pc))
|
||||
{
|
||||
headingBuffer.Append('-');
|
||||
}
|
||||
@@ -81,7 +82,7 @@ namespace Markdig.Helpers
|
||||
while (headingBuffer.Length > 0)
|
||||
{
|
||||
var c = headingBuffer[headingBuffer.Length - 1];
|
||||
if (IsReservedPunctuation(c, false))
|
||||
if (IsReservedPunctuation(c))
|
||||
{
|
||||
headingBuffer.Length--;
|
||||
}
|
||||
@@ -96,10 +97,27 @@ namespace Markdig.Helpers
|
||||
return text;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
private static bool IsReservedPunctuation(char c, bool discardDots)
|
||||
public static string UrilizeAsGfm(string headingText)
|
||||
{
|
||||
return c == '_' || c == '-' || (!discardDots && c == '.');
|
||||
// Following https://github.com/jch/html-pipeline/blob/master/lib/html/pipeline/toc_filter.rb
|
||||
var headingBuffer = StringBuilderCache.Local();
|
||||
for (int i = 0; i < headingText.Length; i++)
|
||||
{
|
||||
var c = char.ToLowerInvariant(headingText[i]);
|
||||
if (char.IsLetterOrDigit(c) || c == ' ' || c == '-' || c == '_')
|
||||
{
|
||||
headingBuffer.Append(c == ' ' ? '-' : c);
|
||||
}
|
||||
}
|
||||
var result = headingBuffer.ToString();
|
||||
headingBuffer.Length = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
private static bool IsReservedPunctuation(char c)
|
||||
{
|
||||
return c == '_' || c == '-' || c == '.';
|
||||
}
|
||||
|
||||
public static bool TryParseAutolink(ref StringSlice text, out string link, out bool isEmail)
|
||||
@@ -496,7 +514,7 @@ namespace Markdig.Helpers
|
||||
return TryParseUrl(ref text, out link);
|
||||
}
|
||||
|
||||
public static bool TryParseUrl<T>(ref T text, out string link) where T : ICharIterator
|
||||
public static bool TryParseUrl<T>(ref T text, out string link, bool isAutoLink = false) where T : ICharIterator
|
||||
{
|
||||
bool isValid = false;
|
||||
var buffer = StringBuilderCache.Local();
|
||||
@@ -593,16 +611,30 @@ namespace Markdig.Helpers
|
||||
|
||||
hasEscape = false;
|
||||
|
||||
if (IsEndOfUri(c))
|
||||
if (IsEndOfUri(c, isAutoLink))
|
||||
{
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '.' && IsEndOfUri(text.PeekChar()))
|
||||
if (isAutoLink)
|
||||
{
|
||||
isValid = true;
|
||||
break;
|
||||
if (c == '&')
|
||||
{
|
||||
int entityNameStart;
|
||||
int entityNameLength;
|
||||
int entityValue;
|
||||
if (HtmlHelper.ScanEntity(text, out entityValue, out entityNameStart, out entityNameLength) > 0)
|
||||
{
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IsTrailingUrlStopCharacter(c) && IsEndOfUri(text.PeekChar(), true))
|
||||
{
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer.Append(c);
|
||||
@@ -621,9 +653,17 @@ namespace Markdig.Helpers
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private static bool IsEndOfUri(char c)
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
private static bool IsTrailingUrlStopCharacter(char c)
|
||||
{
|
||||
return c == '\0' || c.IsSpaceOrTab() || c.IsControl(); // TODO: specs unclear. space is strict or relaxed? (includes tabs?)
|
||||
// Trailing punctuation (specifically, ?, !, ., ,, :, *, _, and ~) will not be considered part of the autolink, though they may be included in the interior of the link:
|
||||
return c == '?' || c == '!' || c == '.' || c == ',' || c == ':' || c == '*' || c == '*' || c == '_' || c == '~';
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
private static bool IsEndOfUri(char c, bool isAutoLink)
|
||||
{
|
||||
return c == '\0' || c.IsSpaceOrTab() || c.IsControl() || (isAutoLink && c == '<'); // TODO: specs unclear. space is strict or relaxed? (includes tabs?)
|
||||
}
|
||||
|
||||
public static bool TryParseLinkReferenceDefinition<T>(T text, out string label, out string url,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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.
|
||||
|
||||
@@ -197,14 +197,14 @@ namespace Markdig.Helpers
|
||||
/// <seealso cref="ICharIterator" />
|
||||
public struct Iterator : ICharIterator
|
||||
{
|
||||
private readonly StringLineGroup lines;
|
||||
private int offset;
|
||||
private readonly StringLineGroup _lines;
|
||||
private int _offset;
|
||||
|
||||
public Iterator(StringLineGroup lines)
|
||||
{
|
||||
this.lines = lines;
|
||||
this._lines = lines;
|
||||
Start = -1;
|
||||
offset = -1;
|
||||
_offset = -1;
|
||||
SliceIndex = 0;
|
||||
CurrentChar = '\0';
|
||||
End = -2;
|
||||
@@ -228,45 +228,47 @@ namespace Markdig.Helpers
|
||||
public char NextChar()
|
||||
{
|
||||
Start++;
|
||||
offset++;
|
||||
_offset++;
|
||||
if (Start <= End)
|
||||
{
|
||||
var slice = (StringSlice)lines.Lines[SliceIndex];
|
||||
if (offset < slice.Length)
|
||||
var slice = (StringSlice)_lines.Lines[SliceIndex];
|
||||
if (_offset < slice.Length)
|
||||
{
|
||||
CurrentChar = slice[slice.Start + offset];
|
||||
CurrentChar = slice[slice.Start + _offset];
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentChar = '\n';
|
||||
SliceIndex++;
|
||||
offset = -1;
|
||||
_offset = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentChar = '\0';
|
||||
Start = End + 1;
|
||||
SliceIndex = lines.Count;
|
||||
offset--;
|
||||
SliceIndex = _lines.Count;
|
||||
_offset--;
|
||||
}
|
||||
return CurrentChar;
|
||||
}
|
||||
|
||||
public char PeekChar()
|
||||
public char PeekChar(int offset = 1)
|
||||
{
|
||||
if (Start + 1 > End)
|
||||
if (offset < 0) throw new ArgumentOutOfRangeException("Negative offset are not supported for StringLineGroup", nameof(offset));
|
||||
|
||||
if (Start + offset > End)
|
||||
{
|
||||
return '\0';
|
||||
}
|
||||
|
||||
var slice = (StringSlice)lines.Lines[SliceIndex];
|
||||
if (offset + 1 >= slice.Length)
|
||||
var slice = (StringSlice)_lines.Lines[SliceIndex];
|
||||
if (_offset + offset >= slice.Length)
|
||||
{
|
||||
return '\n';
|
||||
}
|
||||
|
||||
return slice[slice.Start + offset + 1];
|
||||
return slice[slice.Start + _offset + offset];
|
||||
}
|
||||
|
||||
public bool TrimStart()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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.
|
||||
|
||||
@@ -106,23 +106,12 @@ namespace Markdig.Helpers
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <returns>The character at offset, returns `\0` if none.</returns>
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public char PeekChar(int offset)
|
||||
public char PeekChar(int offset = 1)
|
||||
{
|
||||
var index = Start + offset;
|
||||
return index >= Start && index <= End ? Text[index] : (char) 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Peeks the character immediately after the current <see cref="Start"/> position
|
||||
/// or returns `\0` if after the <see cref="End"/> position.
|
||||
/// </summary>
|
||||
/// <returns>The next character, returns `\0` if none.</returns>
|
||||
[MethodImpl(MethodImplOptionPortable.AggressiveInlining)]
|
||||
public char PeekChar()
|
||||
{
|
||||
return PeekChar(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Peeks a character at the specified offset from the current beginning of the string, without taking into account <see cref="Start"/> and <see cref="End"/>
|
||||
/// </summary>
|
||||
@@ -179,6 +168,28 @@ namespace Markdig.Helpers
|
||||
return i == text.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expect spaces until a end of line. Return <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if whitespaces where matched until a end of line</returns>
|
||||
public bool SkipSpacesToEndOfLineOrEndOfDocument()
|
||||
{
|
||||
for (int i = Start; i <= End; i++)
|
||||
{
|
||||
var c = Text[i];
|
||||
if (c.IsWhitespace())
|
||||
{
|
||||
if (c == '\0' || c == '\n' || (c == '\r' && i + 1 <= End && Text[i + 1] != '\n'))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Matches the specified text using lowercase comparison.
|
||||
/// </summary>
|
||||
|
||||
@@ -5,34 +5,19 @@
|
||||
<Copyright>Alexandre Mutel</Copyright>
|
||||
<AssemblyTitle>Markdig</AssemblyTitle>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<VersionPrefix>0.14.2</VersionPrefix>
|
||||
<VersionPrefix>0.14.8</VersionPrefix>
|
||||
<Authors>Alexandre Mutel</Authors>
|
||||
<TargetFrameworks>net35;net40;portable40-net40+sl5+win8+wp8+wpa81;netstandard1.1;uap10.0</TargetFrameworks>
|
||||
<AssemblyName>Markdig</AssemblyName>
|
||||
<PackageId>Markdig</PackageId>
|
||||
<PackageId Condition="'$(SignAssembly)' == 'true'">Markdig.Signed</PackageId>
|
||||
<PackageTags>Markdown CommonMark md html md2html</PackageTags>
|
||||
<PackageReleaseNotes>
|
||||
> 0.14.2
|
||||
- Fix issue with emphasis preceded/followed by an HTML entity (#157)
|
||||
- Add support for link reference definitions for Normalize renderer (#155)
|
||||
- Add option to disable smiley parsing in EmojiAndSmiley extension
|
||||
> 0.14.1
|
||||
- Fix crash in Markdown.Normalize to handle HtmlBlock correctly
|
||||
- Add better handling of bullet character for lists in Markdown.Normalize
|
||||
> 0.14.0
|
||||
- Add Markdown.ToPlainText, Add option HtmlRenderer.EnableHtmlForBlock.
|
||||
- Add Markdown.Normalize, to allow to normalize a markdown document. Add NormalizeRenderer, to render a MarkdownDocument back to markdown.
|
||||
-
|
||||
> 0.13.4
|
||||
- Add support for single table header row without a table body rows (#141)
|
||||
- ADd support for `nomnoml` diagrams
|
||||
</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/lunet-io/markdig/blob/master/changelog.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/lunet-io/markdig/master/img/markdig.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/lunet-io/markdig</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/lunet-io/markdig/blob/master/license.txt</PackageLicenseUrl>
|
||||
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.1' ">1.6.0</NetStandardImplicitPackageVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net35' ">
|
||||
@@ -65,21 +50,21 @@
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.1' ">
|
||||
<DefineConstants>$(DefineConstants);NETSTANDARD_11;SUPPORT_UNSAFE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'uap10.0' ">
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion Condition="'$(TargetPlatformVersion)' == ''">10.0.10240.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion Condition="'$(TargetPlatformMinVersion)' == ''">10.0.10240.0</TargetPlatformMinVersion>
|
||||
<TargetPlatformMinVersion Condition="'$(TargetPlatformMinVersion)' == ''">10.0.10240.0</TargetPlatformMinVersion>
|
||||
<DefineConstants>$(DefineConstants);NETSTANDARD_11;SUPPORT_UNSAFE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'portable40-net40+sl5+win8+wp8+wpa81'">
|
||||
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>Profile328</TargetFrameworkProfile>
|
||||
<LanguageTargets>$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets</LanguageTargets>
|
||||
</PropertyGroup>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// 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.Text;
|
||||
using Markdig.Helpers;
|
||||
using Markdig.Syntax;
|
||||
using Markdig.Syntax.Inlines;
|
||||
@@ -25,17 +27,18 @@ namespace Markdig.Parsers.Inlines
|
||||
public static bool TryParse(ref StringSlice slice, out string literal, out int match)
|
||||
{
|
||||
literal = null;
|
||||
string entityName;
|
||||
int entityNameStart;
|
||||
int entityNameLength;
|
||||
int entityValue;
|
||||
match = HtmlHelper.ScanEntity(slice.Text, slice.Start, slice.Length, out entityName, out entityValue);
|
||||
match = HtmlHelper.ScanEntity(slice, out entityValue, out entityNameStart, out entityNameLength);
|
||||
if (match == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entityName != null)
|
||||
if (entityNameLength > 0)
|
||||
{
|
||||
literal = EntityHelper.DecodeEntity(entityName);
|
||||
literal = EntityHelper.DecodeEntity(new StringSlice(slice.Text, entityNameStart, entityNameStart + entityNameLength - 1).ToString());
|
||||
}
|
||||
else if (entityValue >= 0)
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace Markdig.Parsers
|
||||
// interpretations of a line, the thematic break takes precedence
|
||||
BlockState result;
|
||||
var thematicParser = ThematicBreakParser.Default;
|
||||
if (thematicParser.HasOpeningCharacter(processor.CurrentChar))
|
||||
if (!(processor.LastBlock is FencedCodeBlock) && thematicParser.HasOpeningCharacter(processor.CurrentChar))
|
||||
{
|
||||
result = thematicParser.TryOpen(processor);
|
||||
if (result.IsBreak())
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Markdig.Renderers.Html.Inlines
|
||||
renderer.Write("mailto:");
|
||||
}
|
||||
renderer.WriteEscapeUrl(obj.Url);
|
||||
renderer.Write('"');
|
||||
renderer.WriteAttributes(obj);
|
||||
|
||||
if (!obj.IsEmail && AutoRelNoFollow)
|
||||
@@ -33,7 +34,7 @@ namespace Markdig.Renderers.Html.Inlines
|
||||
renderer.Write(" rel=\"nofollow\"");
|
||||
}
|
||||
|
||||
renderer.Write("\">");
|
||||
renderer.Write(">");
|
||||
}
|
||||
|
||||
renderer.WriteEscape(obj.Url);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Alexandre Mutel. All rights reserved.
|
||||
// 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;
|
||||
@@ -192,17 +192,16 @@ namespace Markdig.Syntax.Inlines
|
||||
/// <returns><c>true</c> if this instance contains a parent of the specified type; <c>false</c> otherwise</returns>
|
||||
public bool ContainsParentOfType<T>() where T : Inline
|
||||
{
|
||||
var delimiter = this as T;
|
||||
if (delimiter != null)
|
||||
var inline = this;
|
||||
while (inline != null)
|
||||
{
|
||||
return true;
|
||||
var delimiter = inline as T;
|
||||
if (delimiter != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
inline = inline.Parent;
|
||||
}
|
||||
|
||||
if (Parent != null)
|
||||
{
|
||||
return Parent.ContainsParentOfType<T>();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -213,19 +212,15 @@ namespace Markdig.Syntax.Inlines
|
||||
/// <returns>An enumeration on the parents of the specified type</returns>
|
||||
public IEnumerable<T> FindParentOfType<T>() where T : Inline
|
||||
{
|
||||
var parent = Parent;
|
||||
var delimiter = this as T;
|
||||
if (delimiter != null)
|
||||
var inline = this;
|
||||
while (inline != null)
|
||||
{
|
||||
yield return delimiter;
|
||||
}
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
foreach (var previous in parent.FindParentOfType<T>())
|
||||
var delimiter = inline as T;
|
||||
if (delimiter != null)
|
||||
{
|
||||
yield return previous;
|
||||
yield return delimiter;
|
||||
}
|
||||
inline = inline.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.16
|
||||
VisualStudioVersion = 15.0.27004.2005
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{061866E2-005C-4D13-A338-EA464BBEC60F}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\appveyor.yml = ..\appveyor.yml
|
||||
..\changelog.md = ..\changelog.md
|
||||
..\license.txt = ..\license.txt
|
||||
..\readme.md = ..\readme.md
|
||||
EndProjectSection
|
||||
|
||||
Reference in New Issue
Block a user