mirror of
https://github.com/xoofx/markdig.git
synced 2026-02-15 14:05:39 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b366c1a5e3 | ||
|
|
a5e53b014f | ||
|
|
c2f21e21c8 | ||
|
|
81b8dce7a8 | ||
|
|
e6223f86d8 |
@@ -33,6 +33,7 @@ You can **try Markdig online** and compare it to other implementations on [babel
|
||||
- **Definition lists** (inspired from [PHP Markdown Extra - Definitions Lists](https://michelf.ca/projects/php-markdown/extra/#def-list))
|
||||
- **Footnotes** (inspired from [PHP Markdown Extra - Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes))
|
||||
- **Auto-identifiers** for headings (similar to [Pandoc - Auto Identifiers](http://pandoc.org/README.html#extension-auto_identifiers))
|
||||
- **Auto-links** generates links if a text starts with `http://` or `https://` or `ftp://` or `mailto:` or `www.xxx.yyy`
|
||||
- **Task Lists** inspired from [Github Task lists](https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments).
|
||||
- **Extra bullet lists**, supporting alpha bullet `a.` `b.` and roman bullet (`i`, `ii`...etc.)
|
||||
- **Media support** for media url (youtube, vimeo, mp4...etc.) (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/embedded-audio-and-video/441))
|
||||
|
||||
@@ -44,3 +44,27 @@ This is not a nhttp://www.google.com URL but this is (https://www.google.com)
|
||||
.
|
||||
<p>This is not a nhttp://www.google.com URL but this is (<a href="https://www.google.com">https://www.google.com</a>)</p>
|
||||
````````````````````````````````
|
||||
|
||||
An autolink should not interfere with an `<a>` HTML inline:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is an HTML <a href="http://www.google.com">http://www.google.com</a> link
|
||||
.
|
||||
<p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
````````````````````````````````
|
||||
or even within emphasis:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is an HTML <a href="http://www.google.com"> **http://www.google.com** </a> link
|
||||
.
|
||||
<p>This is an HTML <a href="http://www.google.com"> <strong>http://www.google.com</strong> </a> link</p>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
An autolink should not interfere with a markdown link:
|
||||
|
||||
```````````````````````````````` example
|
||||
This is an HTML [http://www.google.com](http://www.google.com) link
|
||||
.
|
||||
<p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
````````````````````````````````
|
||||
|
||||
@@ -20198,4 +20198,64 @@ namespace Markdig.Tests
|
||||
TestParser.TestSpec("This is not a nhttp://www.google.com URL but this is (https://www.google.com)", "<p>This is not a nhttp://www.google.com URL but this is (<a href=\"https://www.google.com\">https://www.google.com</a>)</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
// An autolink should not interfere with an `<a>` HTML inline:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinks
|
||||
{
|
||||
[Test]
|
||||
public void Example004()
|
||||
{
|
||||
// Example 4
|
||||
// Section: Extensions AutoLinks
|
||||
//
|
||||
// The following CommonMark:
|
||||
// This is an HTML <a href="http://www.google.com">http://www.google.com</a> link
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 4, "Extensions AutoLinks");
|
||||
TestParser.TestSpec("This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link", "<p>This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
// or even within emphasis:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinks
|
||||
{
|
||||
[Test]
|
||||
public void Example005()
|
||||
{
|
||||
// Example 5
|
||||
// Section: Extensions AutoLinks
|
||||
//
|
||||
// The following CommonMark:
|
||||
// This is an HTML <a href="http://www.google.com"> **http://www.google.com** </a> link
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is an HTML <a href="http://www.google.com"> <strong>http://www.google.com</strong> </a> link</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 5, "Extensions AutoLinks");
|
||||
TestParser.TestSpec("This is an HTML <a href=\"http://www.google.com\"> **http://www.google.com** </a> link", "<p>This is an HTML <a href=\"http://www.google.com\"> <strong>http://www.google.com</strong> </a> link</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
// An autolink should not interfere with a markdown link:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsAutoLinks
|
||||
{
|
||||
[Test]
|
||||
public void Example006()
|
||||
{
|
||||
// Example 6
|
||||
// Section: Extensions AutoLinks
|
||||
//
|
||||
// The following CommonMark:
|
||||
// This is an HTML [http://www.google.com](http://www.google.com) link
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 6, "Extensions AutoLinks");
|
||||
TestParser.TestSpec("This is an HTML [http://www.google.com](http://www.google.com) link", "<p>This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link</p>", "autolinks|advanced");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Markdig.Extensions.Abbreviations
|
||||
pipeline.BlockParsers.AddIfNotAlready<AbbreviationParser>();
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null && !htmlRenderer.ObjectRenderers.Contains<HtmlAbbreviationRenderer>())
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Markdig.Extensions.AutoIdentifiers
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Markdig.Extensions.AutoLinks
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ namespace Markdig.Extensions.AutoLinks
|
||||
|
||||
public override bool Match(InlineProcessor processor, ref StringSlice slice)
|
||||
{
|
||||
string match;
|
||||
|
||||
// Previous char must be a whitespace or a punctuation
|
||||
var previousChar = slice.PeekCharExtra(-1);
|
||||
if (!previousChar.IsAsciiPunctuation() && !previousChar.IsWhiteSpaceOrZero())
|
||||
@@ -40,6 +38,12 @@ namespace Markdig.Extensions.AutoLinks
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that an autolink is possible in the current context
|
||||
if (!IsAutoLinkValidInCurrentContext(processor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var startPosition = slice.Start;
|
||||
|
||||
var c = slice.CurrentChar;
|
||||
@@ -139,5 +143,55 @@ namespace Markdig.Extensions.AutoLinks
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsAutoLinkValidInCurrentContext(InlineProcessor processor)
|
||||
{
|
||||
// Case where there is a pending HtmlInline <a>
|
||||
var currentInline = processor.Inline;
|
||||
while (currentInline != null)
|
||||
{
|
||||
var htmlInline = currentInline as HtmlInline;
|
||||
if (htmlInline != null)
|
||||
{
|
||||
// If we have a </a> we don't expect nested <a>
|
||||
if (htmlInline.Tag.StartsWith("</a", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// If there is a pending <a>, we can't allow a link
|
||||
if (htmlInline.Tag.StartsWith("<a", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check previous sibling and parents in the tree
|
||||
currentInline = currentInline.PreviousSibling ?? currentInline.Parent;
|
||||
}
|
||||
|
||||
// Check that we don't have any pending brackets opened (where we could have a possible markdown link)
|
||||
// NOTE: This assume that [ and ] are used for links, otherwise autolink will not work properly
|
||||
currentInline = processor.Inline;
|
||||
int countBrackets = 0;
|
||||
while (currentInline != null)
|
||||
{
|
||||
var linkDelimiterInline = currentInline as LinkDelimiterInline;
|
||||
if (linkDelimiterInline != null && linkDelimiterInline.IsActive)
|
||||
{
|
||||
if (linkDelimiterInline.Type == DelimiterType.Open)
|
||||
{
|
||||
countBrackets++;
|
||||
}
|
||||
else if (linkDelimiterInline.Type == DelimiterType.Close)
|
||||
{
|
||||
countBrackets--;
|
||||
}
|
||||
}
|
||||
currentInline = currentInline.Parent;
|
||||
}
|
||||
|
||||
return countBrackets <= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace Markdig.Extensions.Bootstrap
|
||||
pipeline.DocumentProcessed += PipelineOnDocumentProcessed;
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Markdig.Extensions.Citations
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Markdig.Extensions.CustomContainers
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Markdig.Extensions.DefinitionLists
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Markdig.Extensions.Diagrams
|
||||
{
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Markdig.Extensions.Emoji
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Markdig.Extensions.EmphasisExtras
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Markdig.Extensions.Figures
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Markdig.Extensions.Footers
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Markdig.Extensions.Footnotes
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Markdig.Extensions.GenericAttributes
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Markdig.Extensions.Hardlines
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Markdig.Extensions.ListExtras
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Markdig.Extensions.Mathematics
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Markdig.Extensions.MediaLinks
|
||||
{
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Markdig.Extensions.NoRefLinks
|
||||
{
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var linkRenderer = renderer.ObjectRenderers.Find<LinkInlineRenderer>();
|
||||
if (linkRenderer != null)
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Markdig.Extensions.NonAsciiNoEscape
|
||||
{
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Markdig.Extensions.PragmaLines
|
||||
pipeline.DocumentProcessed += PipelineOnDocumentProcessed;
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Markdig.Extensions.SelfPipeline
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Markdig.Extensions.SmartyPants
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Markdig.Extensions.Tables
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null && !htmlRenderer.ObjectRenderers.Contains<HtmlTableRenderer>())
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Markdig.Extensions.Tables
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null && !htmlRenderer.ObjectRenderers.Contains<HtmlTableRenderer>())
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Markdig.Extensions.TaskLists
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Markdig.Extensions.Yaml
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
|
||||
{
|
||||
if (!renderer.ObjectRenderers.Contains<YamlFrontMatterRenderer>())
|
||||
{
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace Markdig
|
||||
/// <summary>
|
||||
/// Setups this extension for the specified renderer.
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline used to parse the document.</param>
|
||||
/// <param name="renderer">The renderer.</param>
|
||||
void Setup(IMarkdownRenderer renderer);
|
||||
void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer);
|
||||
}
|
||||
}
|
||||
@@ -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.ObjectModel;
|
||||
using System.IO;
|
||||
using Markdig.Helpers;
|
||||
using Markdig.Parsers;
|
||||
@@ -34,7 +35,10 @@ namespace Markdig
|
||||
|
||||
internal bool PreciseSourceLocation { get; set; }
|
||||
|
||||
internal OrderedList<IMarkdownExtension> Extensions { get; }
|
||||
/// <summary>
|
||||
/// The read-only list of extensions used to build this pipeline.
|
||||
/// </summary>
|
||||
public OrderedList<IMarkdownExtension> Extensions { get; }
|
||||
|
||||
internal BlockParserList BlockParsers { get; }
|
||||
|
||||
@@ -56,7 +60,7 @@ namespace Markdig
|
||||
if (renderer == null) throw new ArgumentNullException(nameof(renderer));
|
||||
foreach (var extension in Extensions)
|
||||
{
|
||||
extension.Setup(renderer);
|
||||
extension.Setup(this, renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ namespace Markdig
|
||||
{
|
||||
public static partial class Markdown
|
||||
{
|
||||
public const string Version = "0.9.0";
|
||||
public const string Version = "0.10.0";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"title": "Markdig",
|
||||
"version": "0.9.0",
|
||||
"version": "0.10.0",
|
||||
"authors": [ "Alexandre Mutel" ],
|
||||
"description": "A fast, powerfull, CommonMark compliant, extensible Markdown processor for .NET with 20+ builtin extensions (pipetables, footnotes, definition lists... etc.)",
|
||||
"copyright": "Alexandre Mutel",
|
||||
@@ -11,7 +11,7 @@
|
||||
"projectUrl": "https://github.com/lunet-io/markdig",
|
||||
"iconUrl": "https://raw.githubusercontent.com/lunet-io/markdig/master/img/markdig.png",
|
||||
"requireLicenseAcceptance": false,
|
||||
"releaseNotes": "> 0.9.0\n- Add new Autolink extension\n",
|
||||
"releaseNotes": "> 0.10.0\n- Breaking change of the IMarkdownExtension to allow to receive the MarkdownPipeline for the renderers setup\n",
|
||||
"tags": [ "Markdown CommonMark md html md2html" ]
|
||||
},
|
||||
"configurations": {
|
||||
|
||||
Reference in New Issue
Block a user