mirror of
https://github.com/xoofx/markdig.git
synced 2026-02-13 21:42:57 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c1e56aebe | ||
|
|
ed18d3fa25 | ||
|
|
33a6a39c34 | ||
|
|
a1228a1e1c | ||
|
|
d9f1c8c818 | ||
|
|
60350dc9bf | ||
|
|
dbaed0a2bb | ||
|
|
0aa26aeef1 | ||
|
|
09beb2f867 | ||
|
|
fb559af72b | ||
|
|
124b4d6e6e | ||
|
|
4a2d270db1 | ||
|
|
feac9d4125 | ||
|
|
5e77d7b38e | ||
|
|
9f64dcc868 | ||
|
|
7964bd0160 | ||
|
|
191c1e896e | ||
|
|
4bdf1d4d18 | ||
|
|
080dee270d | ||
|
|
7ae36a3794 | ||
|
|
f43d5be0e7 |
141
readme.md
141
readme.md
@@ -1,4 +1,4 @@
|
||||
# Markdig [](https://www.nuget.org/packages/Markdig/)
|
||||
# Markdig [](https://ci.appveyor.com/project/xoofx/markdig) [](https://www.nuget.org/packages/Markdig/)
|
||||
|
||||
Markdig is a fast, powerfull, [CommonMark](http://commonmark.org/) compliant, extensible Markdown processor for .NET.
|
||||
|
||||
@@ -13,32 +13,33 @@ Markdig is a fast, powerfull, [CommonMark](http://commonmark.org/) compliant, ex
|
||||
- Includes all the core elements of CommonMark:
|
||||
- including GFM fenced code blocks.
|
||||
- **Extensible** architecture
|
||||
- Even the core Markdown/CommonMark parsing is pluggable, so it allows to disable builtin Markdown/Commonmark parsing (e.g [Disable HTML parsing](https://github.com/lunet-io/markdig/blob/7964bd0160d4c18e4155127a4c863d61ebd8944a/src/Markdig/MarkdownExtensions.cs#L306)) or change behaviour (e.g change matching `#` of a headers with `@`)
|
||||
- Built-in with **18+ extensions**, including:
|
||||
- **Abbreviations** (inspired from [PHP Markdown Extra - Abbreviations](https://michelf.ca/projects/php-markdown/extra/#abbr))
|
||||
- **Auto-identifiers** for headings (similar to [Pandoc](http://pandoc.org/README.html#extension-auto_identifiers)
|
||||
- **Bootstrap** class (to output bootstrap class)
|
||||
- **Citation** text by enclosing `""...""` (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/referencing-creative-works-with-cite/892))
|
||||
- **Custom containers** similar to fenced code block `:::` for generating a proper `<div>...</div>` instead (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/custom-container-for-block-and-inline/2051))
|
||||
- **Definition lists** (inspired from [PHP Markdown Extra - Definitions Lists](https://michelf.ca/projects/php-markdown/extra/#def-list))
|
||||
- **Emoji** support (inspired from [Markdown-it](https://markdown-it.github.io/))
|
||||
- **Extra emphasis** (inspired from [Pandoc](http://pandoc.org/README.html#strikeout) and [Markdown-it](https://markdown-it.github.io/))
|
||||
- 2 kind of tables:
|
||||
- **Pipe tables** (inspired from Github tables and [PanDoc - Pipe Tables](http://pandoc.org/README.html#extension-pipe_tables))
|
||||
- **Grid tables** (inspired from [Pandoc - Grid Tables](http://pandoc.org/README.html#extension-grid_tables))
|
||||
- **Extra emphasis** (inspired from [Pandoc - Emphasis](http://pandoc.org/README.html#strikeout) and [Markdown-it](https://markdown-it.github.io/))
|
||||
- strike through `~~`,
|
||||
- Subscript `~`
|
||||
- Superscript `^`
|
||||
- Inserted `++`
|
||||
- Marked `==`
|
||||
- **Special attributes** or attached HTML attributes (inspired from [PHP Markdown Extra - Special Attributes](https://michelf.ca/projects/php-markdown/extra/#spe-attr))
|
||||
- **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))
|
||||
- **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))
|
||||
- **Abbreviations** (inspired from [PHP Markdown Extra - Abbreviations](https://michelf.ca/projects/php-markdown/extra/#abbr))
|
||||
- **Citation** text by enclosing `""...""` (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/referencing-creative-works-with-cite/892))
|
||||
- **Custom containers** similar to fenced code block `:::` for generating a proper `<div>...</div>` instead (inspired by this [CommonMark discussion ](https://talk.commonmark.org/t/custom-container-for-block-and-inline/2051))
|
||||
- **Figures** (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/image-tag-should-expand-to-figure-when-used-with-title/265/5))
|
||||
- **Footers** (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/syntax-for-footer/2070))
|
||||
- **Footnotes** (inspired from [PHP Markdown Extra - Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes))
|
||||
- **Special attributes** or attached HTML attributes (inspired from [PHP Markdown Extra - Footnotes](https://michelf.ca/projects/php-markdown/extra/#spe-attr))
|
||||
- **Soft lines as hard lines**
|
||||
- **Extra bullet lists**, supporting alpha bullet `a.` `b.` and roman bullet (`i`, `ii`...etc.)
|
||||
- **Mathematics**/Latex extension by enclosing `$$` for block and `$` for inline math (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/mathematics-extension/457/31))
|
||||
- **Embed player** for media url (youtube, vimeo, mp4...etc.) (inspired from this [CommonMark discussion](https://talk.commonmark.org/t/embedded-audio-and-video/441))
|
||||
- **Soft lines as hard lines**
|
||||
- **Emoji** support (inspired from [Markdown-it](https://markdown-it.github.io/))
|
||||
- **SmartyPants** (inspired from [Daring Fireball - SmartyPants](https://daringfireball.net/projects/smartypants/))
|
||||
- Tables:
|
||||
- **Pipe tables** (inspired from Kramdown/[PanDoc](http://pandoc.org/README.html#pipe_tables))
|
||||
- **Grid tables** (inspired from [Pandoc](http://pandoc.org/README.html#grid_tables))
|
||||
- **Bootstrap** class (to output bootstrap class)
|
||||
- Compatible with .NET 3.5, 4.0+ and .NET Core (`netstandard1.1+`)
|
||||
|
||||
## Download
|
||||
@@ -47,40 +48,110 @@ Markdig is available as a NuGet package: [;
|
||||
var result = Markdown.ToHtml("This is a text with some *emphasis*");
|
||||
Console.WriteLine(result); // prints: <p>This is a text with some <em>emphasis</em></p>
|
||||
```
|
||||
|
||||
In order to activate all extensions (except Emoji)
|
||||
|
||||
```csharp
|
||||
var result = Markdown.ToHtml("This is a text with some **emphasis**", new MarkdownPipeline().UseAllExtensions());
|
||||
// Configure the pipeline with all extensions active
|
||||
var pipeline = new MarkdownPipelineBuilder().UseAllExtensions().Build();
|
||||
var result = Markdown.ToHtml("This is a text with some *emphasis*", pipeline);
|
||||
```
|
||||
|
||||
You can have a look at the [MarkdownPipeline](https://github.com/lunet-io/markdig/blob/src/Markdig/MarkdownPipeline.cs) file that describes all actionable extensions.
|
||||
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)
|
||||
|
||||
## License
|
||||
|
||||
This software is released under the [BSD-Clause 2 license](http://opensource.org/licenses/BSD-2-Clause).
|
||||
This software is released under the [BSD-Clause 2 license](https://github.com/lunet-io/markdig/blob/master/license.txt).
|
||||
|
||||
|
||||
## Benchmarking
|
||||
|
||||
This is an early preview of the benchmarking against various implementations:
|
||||
|
||||
- Markdig: itself
|
||||
- CommonMarkCpp: [cmark](https://github.com/jgm/cmark), Reference C implementation of CommonMark, no support for extensions
|
||||
- [CommonMark.NET](https://github.com/Knagis/CommonMark.NET): CommonMark implementation for .NET, no support for extensions, port of cmark
|
||||
- [CommonMarkNet (devel)](https://github.com/AMDL/CommonMark.NET/tree/pipe-tables): An evolution of CommonMark.NET, supports extensions, not released yet
|
||||
- [MarkdownDeep](https://github.com/toptensoftware/markdowndeep) another .NET implementation
|
||||
- [MarkdownSharp](https://github.com/Kiri-rin/markdownsharp): Open source C# implementation of Markdown processor, as featured on Stack Overflow, regexp based.
|
||||
- [Moonshine](https://github.com/brandonc/moonshine): popular C Markdown processor
|
||||
|
||||
Markdig is roughly x100 times faster than MarkdownSharp and extremelly competitive to other implems (that are not feature wise comparable)
|
||||
|
||||
Performance in x86:
|
||||
|
||||
```
|
||||
// * Summary *
|
||||
|
||||
BenchmarkDotNet-Dev=v0.9.6.0+
|
||||
OS=Microsoft Windows NT 6.2.9200.0
|
||||
Processor=Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, ProcessorCount=8
|
||||
Frequency=3319351 ticks, Resolution=301.2637 ns, Timer=TSC
|
||||
HostCLR=MS.NET 4.0.30319.42000, Arch=32-bit RELEASE
|
||||
JitModules=clrjit-v4.6.1080.0
|
||||
|
||||
Type=Program Mode=SingleRun LaunchCount=2
|
||||
WarmupCount=2 TargetCount=10
|
||||
|
||||
Method | Median | StdDev | Gen 0 | Gen 1 | Gen 2 | Bytes Allocated/Op |
|
||||
--------------------- |---------- |---------- |------- |------ |------- |------------------- |
|
||||
TestMarkdig | 5.4870 ms | 0.0158 ms | 193.00 | 12.00 | 84.00 | 1,425,192.72 |
|
||||
TestCommonMarkCpp | 4.0134 ms | 0.1008 ms | - | - | 180.00 | 454,859.74 |
|
||||
TestCommonMarkNet | 4.6139 ms | 0.0581 ms | 193.00 | 12.00 | 84.00 | 1,406,367.27 |
|
||||
TestCommonMarkNetNew | 5.5327 ms | 0.0461 ms | 193.00 | 96.00 | 84.00 | 1,738,465.42 |
|
||||
TestMarkdownDeep | 7.5910 ms | 0.1006 ms | 205.00 | 96.00 | 84.00 | 1,758,383.79 |
|
||||
TestMoonshine | 5.8843 ms | 0.1758 ms | - | - | 215.00 | 565,000.73 |
|
||||
|
||||
// * Diagnostic Output - MemoryDiagnoser *
|
||||
|
||||
|
||||
// ***** BenchmarkRunner: End *****
|
||||
```
|
||||
|
||||
Performance for x64:
|
||||
|
||||
```
|
||||
// * Summary *
|
||||
|
||||
BenchmarkDotNet-Dev=v0.9.6.0+
|
||||
OS=Microsoft Windows NT 6.2.9200.0
|
||||
Processor=Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, ProcessorCount=8
|
||||
Frequency=3319351 ticks, Resolution=301.2637 ns, Timer=TSC
|
||||
HostCLR=MS.NET 4.0.30319.42000, Arch=64-bit RELEASE [RyuJIT]
|
||||
JitModules=clrjit-v4.6.1080.0
|
||||
|
||||
Type=Program Mode=SingleRun LaunchCount=2
|
||||
WarmupCount=2 TargetCount=10
|
||||
|
||||
Method | Median | StdDev | Gen 0 | Gen 1 | Gen 2 | Bytes Allocated/Op |
|
||||
--------------------- |---------- |---------- |------- |------- |------ |------------------- |
|
||||
TestMarkdig | 5.9539 ms | 0.0495 ms | 157.00 | 96.00 | 84.00 | 1,767,834.52 |
|
||||
TestCommonMarkNet | 4.3158 ms | 0.0161 ms | 157.00 | 96.00 | 84.00 | 1,747,432.06 |
|
||||
TestCommonMarkNetNew | 5.3421 ms | 0.0435 ms | 229.00 | 168.00 | 84.00 | 2,323,922.97 |
|
||||
TestMarkdownDeep | 7.4750 ms | 0.0281 ms | 318.00 | 186.00 | 84.00 | 2,576,728.69 |
|
||||
|
||||
// * Diagnostic Output - MemoryDiagnoser *
|
||||
|
||||
|
||||
// ***** BenchmarkRunner: End *****
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
Thanks to the fantastic work done by [John Mac Farlane](http://johnmacfarlane.net/) for the CommonMark specs and all the people involved in making Markdown a better standard!
|
||||
|
||||
This project would not have been possible without this huge foundation.
|
||||
|
||||
Thanks also to the project [BenchmarkDotNet](https://github.com/PerfDotNet/BenchmarkDotNet) that makes benchmarking so easy to setup!
|
||||
|
||||
## Author
|
||||
|
||||
Alexandre MUTEL aka [xoofx](http://xoofx.com)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,14 +38,14 @@ namespace Markdig.Tests
|
||||
{
|
||||
if (string.IsNullOrEmpty(extensionsGroupText))
|
||||
{
|
||||
yield return new MarkdownPipeline();
|
||||
yield return new MarkdownPipelineBuilder().Build();
|
||||
yield break;
|
||||
}
|
||||
|
||||
var extensionGroups = extensionsGroupText.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var extensionsText in extensionGroups)
|
||||
{
|
||||
var pipeline = new MarkdownPipeline();
|
||||
var pipeline = new MarkdownPipelineBuilder();
|
||||
foreach (var extension in extensionsText.Split(new[] { '+' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
switch (extension.ToLowerInvariant())
|
||||
@@ -113,7 +113,7 @@ namespace Markdig.Tests
|
||||
}
|
||||
}
|
||||
|
||||
yield return pipeline;
|
||||
yield return pipeline.Build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,39 +22,52 @@ Later in a text we are using HTML and it becomes an abbr tag HTML
|
||||
//");
|
||||
|
||||
//var result = Markdown.ToHtml(text, new MarkdownPipeline().UseFootnotes().UseEmphasisExtra());
|
||||
var result = Markdown.ToHtml(text, new MarkdownPipeline().UseAbbreviation());
|
||||
var result = Markdown.ToHtml(text, new MarkdownPipelineBuilder().UseAbbreviation().Build());
|
||||
//File.WriteAllText("test.html", result, Encoding.UTF8);
|
||||
Console.WriteLine(result);
|
||||
}
|
||||
|
||||
// Test for emoji and smileys
|
||||
// var text = @" This is a test with a :) and a :angry: smiley";
|
||||
[Test]
|
||||
public void TestSamePipelineAllExtensions()
|
||||
{
|
||||
var pipeline = new MarkdownPipelineBuilder().UseAllExtensions().Build();
|
||||
|
||||
// Reuse the same pipeline
|
||||
var result1 = Markdown.ToHtml("This is a \"\"citation\"\"", pipeline);
|
||||
var result2 = Markdown.ToHtml("This is a \"\"citation\"\"", pipeline);
|
||||
|
||||
Assert.AreEqual("<p>This is a <cite>citation</cite></p>", result1.Trim());
|
||||
Assert.AreEqual(result1, result2);
|
||||
}
|
||||
|
||||
// Test for emoji and smileys
|
||||
// var text = @" This is a test with a :) and a :angry: smiley";
|
||||
|
||||
|
||||
// Test for definition lists:
|
||||
//
|
||||
// var text = @"
|
||||
//Term 1
|
||||
//: This is a definition item
|
||||
// With a paragraph
|
||||
// > This is a block quote
|
||||
// Test for definition lists:
|
||||
//
|
||||
// var text = @"
|
||||
//Term 1
|
||||
//: This is a definition item
|
||||
// With a paragraph
|
||||
// > This is a block quote
|
||||
|
||||
// - This is a list
|
||||
// - item2
|
||||
// - This is a list
|
||||
// - item2
|
||||
|
||||
// ```java
|
||||
// Test
|
||||
// ```java
|
||||
// Test
|
||||
|
||||
|
||||
// ```
|
||||
// ```
|
||||
|
||||
// And a lazy line
|
||||
//: This ia another definition item
|
||||
// And a lazy line
|
||||
//: This ia another definition item
|
||||
|
||||
//Term2
|
||||
//Term3 *with some inline*
|
||||
//: This is another definition for term2
|
||||
//";
|
||||
//Term2
|
||||
//Term3 *with some inline*
|
||||
//: This is another definition for term2
|
||||
//";
|
||||
|
||||
|
||||
// Test for grid table
|
||||
|
||||
@@ -12,18 +12,18 @@ namespace Markdig.Extensions.Abbreviations
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class AbbreviationExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.BlockParsers.AddIfNotAlready<AbbreviationParser>();
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null && !htmlRenderer.ObjectRenderers.Contains<HtmlAbbreviationRenderer>())
|
||||
{
|
||||
if (!htmlRenderer.ObjectRenderers.Contains<HtmlAbbreviationRenderer>())
|
||||
{
|
||||
// Must be inserted before CodeBlockRenderer
|
||||
htmlRenderer.ObjectRenderers.Insert(0, new HtmlAbbreviationRenderer());
|
||||
}
|
||||
// Must be inserted before CodeBlockRenderer
|
||||
htmlRenderer.ObjectRenderers.Insert(0, new HtmlAbbreviationRenderer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Markdig.Extensions.AutoIdentifiers
|
||||
};
|
||||
}
|
||||
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
var headingBlockParser = pipeline.BlockParsers.Find<HeadingBlockParser>();
|
||||
if (headingBlockParser != null)
|
||||
@@ -59,6 +59,10 @@ namespace Markdig.Extensions.AutoIdentifiers
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process on a new <see cref="HeadingBlock"/>
|
||||
/// </summary>
|
||||
|
||||
@@ -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.Renderers;
|
||||
using Markdig.Renderers.Html;
|
||||
using Markdig.Syntax;
|
||||
using Markdig.Syntax.Inlines;
|
||||
@@ -14,13 +15,17 @@ namespace Markdig.Extensions.Bootstrap
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class BootstrapExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
// Make sure we don't have a delegate twice
|
||||
pipeline.DocumentProcessed -= PipelineOnDocumentProcessed;
|
||||
pipeline.DocumentProcessed += PipelineOnDocumentProcessed;
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
private static void PipelineOnDocumentProcessed(MarkdownDocument document)
|
||||
{
|
||||
foreach(var node in document.Descendants())
|
||||
|
||||
@@ -15,28 +15,25 @@ namespace Markdig.Extensions.Cites
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class CiteExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
var parser = pipeline.InlineParsers.FindExact<EmphasisInlineParser>();
|
||||
if (parser != null)
|
||||
if (parser != null && !parser.HasEmphasisChar('"'))
|
||||
{
|
||||
foreach (var emphasis in parser.EmphasisDescriptors)
|
||||
{
|
||||
if (emphasis.Character == '"')
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
parser.EmphasisDescriptors.Add(new EmphasisDescriptor('"', 2, 2, false));
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
// Extend the rendering here.
|
||||
var emphasisRenderer = htmlRenderer.ObjectRenderers.FindExact<EmphasisInlineRenderer>();
|
||||
var emphasisRenderer = renderer.ObjectRenderers.FindExact<EmphasisInlineRenderer>();
|
||||
if (emphasisRenderer != null)
|
||||
{
|
||||
// TODO: Use an ordered list instead as we don't know if this specific GetTag has been already added
|
||||
var previousTag = emphasisRenderer.GetTag;
|
||||
emphasisRenderer.GetTag = inline => GetTag(inline) ?? previousTag(inline);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Markdig.Extensions.CustomContainers
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class CustomContainerExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.BlockParsers.Contains<CustomContainerParser>())
|
||||
{
|
||||
@@ -23,7 +23,7 @@ namespace Markdig.Extensions.CustomContainers
|
||||
|
||||
// Plug the inline parser for CustomContainerInline
|
||||
var inlineParser = pipeline.InlineParsers.Find<EmphasisInlineParser>();
|
||||
if (inlineParser != null)
|
||||
if (inlineParser != null && !inlineParser.HasEmphasisChar(':'))
|
||||
{
|
||||
inlineParser.EmphasisDescriptors.Add(new EmphasisDescriptor(':', 2, 2, true));
|
||||
var previousCreateEmphasisInline = inlineParser.CreateEmphasisInline;
|
||||
@@ -36,8 +36,11 @@ namespace Markdig.Extensions.CustomContainers
|
||||
return previousCreateEmphasisInline?.Invoke(emphasisChar, strong);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
if (!htmlRenderer.ObjectRenderers.Contains<HtmlCustomContainerRenderer>())
|
||||
@@ -51,6 +54,7 @@ namespace Markdig.Extensions.CustomContainers
|
||||
htmlRenderer.ObjectRenderers.Insert(0, new HtmlCustomContainerInlineRenderer());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,18 @@ namespace Markdig.Extensions.DefinitionLists
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class DefinitionListExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.BlockParsers.Contains<DefinitionListParser>())
|
||||
{
|
||||
// Insert the parser before any other parsers
|
||||
pipeline.BlockParsers.Insert(0, new DefinitionListParser());
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
if (!htmlRenderer.ObjectRenderers.Contains<HtmlDefinitionListRenderer>())
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// This file is licensed under the BSD-Clause 2 license.
|
||||
// See the license.txt file in the project root for more information.
|
||||
|
||||
using Markdig.Renderers;
|
||||
|
||||
namespace Markdig.Extensions.Emoji
|
||||
{
|
||||
/// <summary>
|
||||
@@ -10,7 +12,7 @@ namespace Markdig.Extensions.Emoji
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class EmojiExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.InlineParsers.Contains<EmojiParser>())
|
||||
{
|
||||
@@ -18,5 +20,9 @@ namespace Markdig.Extensions.Emoji
|
||||
pipeline.InlineParsers.Insert(0, new EmojiParser());
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ namespace Markdig.Extensions.EmphasisExtra
|
||||
/// </summary>
|
||||
public EmphasisExtraOptions Options { get; }
|
||||
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
var parser = pipeline.InlineParsers.FindExact<EmphasisInlineParser>();
|
||||
if (parser != null)
|
||||
@@ -83,8 +83,11 @@ namespace Markdig.Extensions.EmphasisExtra
|
||||
parser.EmphasisDescriptors.Add(new EmphasisDescriptor('=', 2, 2, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
// Extend the rendering here.
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Markdig.Extensions.Figures
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class FigureExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.BlockParsers.Contains<FigureBlockParser>())
|
||||
{
|
||||
@@ -28,7 +28,11 @@ namespace Markdig.Extensions.Figures
|
||||
pipeline.BlockParsers.Insert(0, new FigureBlockParser());
|
||||
}
|
||||
}
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
htmlRenderer.ObjectRenderers.AddIfNotAlready<HtmlFigureRenderer>();
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Markdig.Extensions.Footers
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class FooterExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.BlockParsers.Contains<FooterBlockParser>())
|
||||
{
|
||||
@@ -27,8 +27,11 @@ namespace Markdig.Extensions.Footers
|
||||
pipeline.BlockParsers.Insert(0, new FooterBlockParser());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
htmlRenderer.ObjectRenderers.AddIfNotAlready(new HtmlFooterBlockRenderer());
|
||||
|
||||
@@ -11,15 +11,18 @@ namespace Markdig.Extensions.Footnotes
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class FootnoteExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.BlockParsers.Contains<FootnoteParser>())
|
||||
{
|
||||
// Insert the parser before any other parsers
|
||||
pipeline.BlockParsers.Insert(0, new FootnoteParser());
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
htmlRenderer.ObjectRenderers.AddIfNotAlready(new HtmlFootnoteGroupRenderer());
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using Markdig.Helpers;
|
||||
using Markdig.Parsers;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Renderers.Html;
|
||||
using Markdig.Syntax;
|
||||
using Markdig.Syntax.Inlines;
|
||||
@@ -18,7 +19,7 @@ namespace Markdig.Extensions.GenericAttributes
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class GenericAttributesExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.InlineParsers.Contains<GenericAttributesParser>())
|
||||
{
|
||||
@@ -36,6 +37,10 @@ namespace Markdig.Extensions.GenericAttributes
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
private bool TryProcessAttributesForHeading(BlockProcessor processor, ref StringSlice line, IBlock block)
|
||||
{
|
||||
// Try to find if there is any attributes { in the info string on the first line of a FencedCodeBlock
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the license.txt file in the project root for more information.
|
||||
|
||||
using Markdig.Parsers.Inlines;
|
||||
using Markdig.Renderers;
|
||||
|
||||
namespace Markdig.Extensions.Hardlines
|
||||
{
|
||||
@@ -12,7 +13,7 @@ namespace Markdig.Extensions.Hardlines
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class SoftlineBreakAsHardlineExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
// Simply modify the LineBreakInlineParser
|
||||
// TODO: We might want more options (like pandoc)
|
||||
@@ -22,5 +23,9 @@ namespace Markdig.Extensions.Hardlines
|
||||
parser.EnableSoftAsHard = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the license.txt file in the project root for more information.
|
||||
|
||||
using Markdig.Parsers;
|
||||
using Markdig.Renderers;
|
||||
|
||||
namespace Markdig.Extensions.ListExtra
|
||||
{
|
||||
@@ -12,7 +13,7 @@ namespace Markdig.Extensions.ListExtra
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class ListExtraExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
var parser = pipeline.BlockParsers.Find<ListBlockParser>();
|
||||
if (parser != null)
|
||||
@@ -20,5 +21,9 @@ namespace Markdig.Extensions.ListExtra
|
||||
parser.ItemParsers.AddIfNotAlready<ListExtraItemParser>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace Markdig.Extensions.Mathematics
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class MathExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
// Adds the inline parser
|
||||
if (!pipeline.InlineParsers.Contains<MathInlineParser>())
|
||||
@@ -27,8 +27,11 @@ namespace Markdig.Extensions.Mathematics
|
||||
// Insert before EmphasisInlineParser to take precedence
|
||||
pipeline.BlockParsers.Insert(0, new MathBlockParser());
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
if (!htmlRenderer.ObjectRenderers.Contains<HtmlMathInlineRenderer>())
|
||||
|
||||
@@ -26,9 +26,13 @@ namespace Markdig.Extensions.Medias
|
||||
|
||||
public MediaOptions Options { get; }
|
||||
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
var inlineRenderer = htmlRenderer.ObjectRenderers.FindExact<LinkInlineRenderer>();
|
||||
|
||||
@@ -26,15 +26,18 @@ namespace Markdig.Extensions.SmartyPants
|
||||
/// </summary>
|
||||
public SmartyPantOptions Options { get; }
|
||||
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.InlineParsers.Contains<SmaryPantsInlineParser>())
|
||||
{
|
||||
// Insert the parser after the code span parser
|
||||
pipeline.InlineParsers.InsertAfter<CodeInlineParser>(new SmaryPantsInlineParser());
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null)
|
||||
{
|
||||
if (!htmlRenderer.ObjectRenderers.Contains<HtmlSmartyPantRenderer>())
|
||||
|
||||
@@ -11,14 +11,17 @@ namespace Markdig.Extensions.Tables
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class GridTableExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.BlockParsers.Contains<GridTableParser>())
|
||||
{
|
||||
pipeline.BlockParsers.Insert(0, new GridTableParser());
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null && !htmlRenderer.ObjectRenderers.Contains<HtmlTableRenderer>())
|
||||
{
|
||||
htmlRenderer.ObjectRenderers.Add(new HtmlTableRenderer());
|
||||
|
||||
@@ -26,14 +26,17 @@ namespace Markdig.Extensions.Tables
|
||||
/// </summary>
|
||||
public PipeTableOptions Options { get; }
|
||||
|
||||
public void Setup(MarkdownPipeline pipeline)
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
if (!pipeline.InlineParsers.Contains<PipeTableParser>())
|
||||
{
|
||||
pipeline.InlineParsers.InsertBefore<EmphasisInlineParser>(new PipeTableParser(Options));
|
||||
}
|
||||
}
|
||||
|
||||
var htmlRenderer = pipeline.Renderer as HtmlRenderer;
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
var htmlRenderer = renderer as HtmlRenderer;
|
||||
if (htmlRenderer != null && !htmlRenderer.ObjectRenderers.Contains<HtmlTableRenderer>())
|
||||
{
|
||||
htmlRenderer.ObjectRenderers.Add(new HtmlTableRenderer());
|
||||
|
||||
@@ -14,6 +14,14 @@ namespace Markdig.Helpers
|
||||
/// <remarks>We use a typed list and don't use extension methods because it would pollute all list implemts and the top level namespace.</remarks>
|
||||
public class OrderedList<T> : List<T>
|
||||
{
|
||||
public OrderedList()
|
||||
{
|
||||
}
|
||||
|
||||
public OrderedList(IEnumerable<T> collection) : base(collection)
|
||||
{
|
||||
}
|
||||
|
||||
public bool InsertBefore<TElement>(T element) where TElement : T
|
||||
{
|
||||
if (element == null) throw new ArgumentNullException(nameof(element));
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// 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.Renderers;
|
||||
|
||||
namespace Markdig
|
||||
{
|
||||
/// <summary>
|
||||
@@ -12,6 +15,12 @@ namespace Markdig
|
||||
/// Setups this extension for the specified pipeline.
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
void Setup(MarkdownPipeline pipeline);
|
||||
void Setup(MarkdownPipelineBuilder pipeline);
|
||||
|
||||
/// <summary>
|
||||
/// Setups this extension for the specified renderer.
|
||||
/// </summary>
|
||||
/// <param name="renderer">The renderer.</param>
|
||||
void Setup(IMarkdownRenderer renderer);
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,18 @@
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>8A58A7E2-627C-4F41-933F-5AC92ADFAB48</ProjectGuid>
|
||||
<RootNamespace>Markdig</RootNamespace>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\Bin</OutputPath>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
|
||||
<TypeScriptCompileBlocked>True</TypeScriptCompileBlocked>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
@@ -12,7 +12,7 @@ namespace Markdig
|
||||
/// <summary>
|
||||
/// Provides methods for parsing a Markdown string to a syntax tree and converting it to other formats.
|
||||
/// </summary>
|
||||
public static class Markdown
|
||||
public static partial class Markdown
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a Markdown string to HTML.
|
||||
@@ -54,33 +54,33 @@ namespace Markdig
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException(nameof(reader));
|
||||
if (writer == null) throw new ArgumentNullException(nameof(writer));
|
||||
pipeline = pipeline ?? new MarkdownPipeline();
|
||||
pipeline = pipeline ?? new MarkdownPipelineBuilder().Build();
|
||||
|
||||
// We override the renderer with our own writer
|
||||
pipeline.Renderer = new HtmlRenderer(writer);
|
||||
var renderer = new HtmlRenderer(writer);
|
||||
pipeline.Setup(renderer);
|
||||
|
||||
var document = Parse(reader, pipeline);
|
||||
pipeline.Renderer.Render(document);
|
||||
renderer.Render(document);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Markdown string using a custom <see cref="IMarkdownRenderer"/> specified in the <see cref="MarkdownPipeline.Renderer"/>.
|
||||
/// Converts a Markdown string using a custom <see cref="IMarkdownRenderer"/>.
|
||||
/// </summary>
|
||||
/// <param name="reader">A Markdown text from a <see cref="TextReader"/>.</param>
|
||||
/// <param name="renderer">The renderer to convert Markdown to.</param>
|
||||
/// <param name="pipeline">The pipeline used for the conversion.</param>
|
||||
/// <exception cref="System.ArgumentNullException">if reader or writer variable are null</exception>
|
||||
public static object Convert(TextReader reader, MarkdownPipeline pipeline = null)
|
||||
public static object Convert(TextReader reader, IMarkdownRenderer renderer, MarkdownPipeline pipeline = null)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException(nameof(reader));
|
||||
pipeline = pipeline ?? new MarkdownPipeline();
|
||||
if (pipeline.Renderer == null)
|
||||
{
|
||||
throw new InvalidOperationException("The property MarkdownPipeline.Renderer cannot be null");
|
||||
}
|
||||
if (renderer == null) throw new ArgumentNullException(nameof(renderer));
|
||||
pipeline = pipeline ?? new MarkdownPipelineBuilder().Build();
|
||||
|
||||
var document = Parse(reader, pipeline);
|
||||
return pipeline.Renderer.Render(document);
|
||||
pipeline.Setup(renderer);
|
||||
return renderer.Render(document);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -92,7 +92,7 @@ namespace Markdig
|
||||
public static MarkdownDocument Parse(string markdown)
|
||||
{
|
||||
if (markdown == null) throw new ArgumentNullException(nameof(markdown));
|
||||
return Parse(new StringReader(markdown), new MarkdownPipeline());
|
||||
return Parse(new StringReader(markdown));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -105,7 +105,7 @@ namespace Markdig
|
||||
public static MarkdownDocument Parse(TextReader reader, MarkdownPipeline pipeline = null)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException(nameof(reader));
|
||||
pipeline = pipeline ?? new MarkdownPipeline();
|
||||
pipeline = pipeline ?? new MarkdownPipelineBuilder().Build();
|
||||
|
||||
return MarkdownParser.Parse(reader, pipeline);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ using Markdig.Extensions.Mathematics;
|
||||
using Markdig.Extensions.Medias;
|
||||
using Markdig.Extensions.SmartyPants;
|
||||
using Markdig.Extensions.Tables;
|
||||
using Markdig.Parsers;
|
||||
using Markdig.Parsers.Inlines;
|
||||
|
||||
namespace Markdig
|
||||
{
|
||||
@@ -32,7 +34,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseAllExtensions(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseAllExtensions(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
return pipeline
|
||||
.UseAbbreviation()
|
||||
@@ -59,7 +61,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseCustomContainer(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseCustomContainer(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<CustomContainerExtension>();
|
||||
return pipeline;
|
||||
@@ -73,7 +75,7 @@ namespace Markdig
|
||||
/// <returns>
|
||||
/// The modified pipeline
|
||||
/// </returns>
|
||||
public static MarkdownPipeline UseMedia(this MarkdownPipeline pipeline, MediaOptions options = null)
|
||||
public static MarkdownPipelineBuilder UseMedia(this MarkdownPipelineBuilder pipeline, MediaOptions options = null)
|
||||
{
|
||||
if (!pipeline.Extensions.Contains<MediaExtension>())
|
||||
{
|
||||
@@ -90,7 +92,7 @@ namespace Markdig
|
||||
/// <returns>
|
||||
/// The modified pipeline
|
||||
/// </returns>
|
||||
public static MarkdownPipeline UseAutoIdentifier(this MarkdownPipeline pipeline, AutoIdentifierOptions options = AutoIdentifierOptions.Default)
|
||||
public static MarkdownPipelineBuilder UseAutoIdentifier(this MarkdownPipelineBuilder pipeline, AutoIdentifierOptions options = AutoIdentifierOptions.Default)
|
||||
{
|
||||
if (!pipeline.Extensions.Contains<AutoIdentifierExtension>())
|
||||
{
|
||||
@@ -107,7 +109,7 @@ namespace Markdig
|
||||
/// <returns>
|
||||
/// The modified pipeline
|
||||
/// </returns>
|
||||
public static MarkdownPipeline UseSmartyPants(this MarkdownPipeline pipeline, SmartyPantOptions options = null)
|
||||
public static MarkdownPipelineBuilder UseSmartyPants(this MarkdownPipelineBuilder pipeline, SmartyPantOptions options = null)
|
||||
{
|
||||
if (!pipeline.Extensions.Contains<SmartyPantsExtension>())
|
||||
{
|
||||
@@ -121,7 +123,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseBootstrap(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseBootstrap(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<BootstrapExtension>();
|
||||
return pipeline;
|
||||
@@ -132,7 +134,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseMath(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseMath(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<MathExtension>();
|
||||
return pipeline;
|
||||
@@ -143,7 +145,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseFigure(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseFigure(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<FigureExtension>();
|
||||
return pipeline;
|
||||
@@ -154,7 +156,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseAbbreviation(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseAbbreviation(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<AbbreviationExtension>();
|
||||
return pipeline;
|
||||
@@ -165,7 +167,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseDefinitionList(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseDefinitionList(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<DefinitionListExtension>();
|
||||
return pipeline;
|
||||
@@ -179,7 +181,7 @@ namespace Markdig
|
||||
/// <returns>
|
||||
/// The modified pipeline
|
||||
/// </returns>
|
||||
public static MarkdownPipeline UsePipeTable(this MarkdownPipeline pipeline, PipeTableOptions options = null)
|
||||
public static MarkdownPipelineBuilder UsePipeTable(this MarkdownPipelineBuilder pipeline, PipeTableOptions options = null)
|
||||
{
|
||||
if (!pipeline.Extensions.Contains<PipeTableExtension>())
|
||||
{
|
||||
@@ -193,7 +195,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseGridTable(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseGridTable(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<GridTableExtension>();
|
||||
return pipeline;
|
||||
@@ -205,7 +207,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseCite(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseCite(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<CiteExtension>();
|
||||
return pipeline;
|
||||
@@ -216,7 +218,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseFooter(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseFooter(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<FooterExtension>();
|
||||
return pipeline;
|
||||
@@ -227,7 +229,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseFootnotes(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseFootnotes(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<FootnoteExtension>();
|
||||
return pipeline;
|
||||
@@ -238,7 +240,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseSoftlineBreakAsHardlineBreak(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseSoftlineBreakAsHardlineBreak(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<SoftlineBreakAsHardlineExtension>();
|
||||
return pipeline;
|
||||
@@ -252,7 +254,7 @@ namespace Markdig
|
||||
/// <returns>
|
||||
/// The modified pipeline
|
||||
/// </returns>
|
||||
public static MarkdownPipeline UseEmphasisExtra(this MarkdownPipeline pipeline, EmphasisExtraOptions options = EmphasisExtraOptions.Default)
|
||||
public static MarkdownPipelineBuilder UseEmphasisExtra(this MarkdownPipelineBuilder pipeline, EmphasisExtraOptions options = EmphasisExtraOptions.Default)
|
||||
{
|
||||
if (!pipeline.Extensions.Contains<EmphasisExtraExtension>())
|
||||
{
|
||||
@@ -268,7 +270,7 @@ namespace Markdig
|
||||
/// <returns>
|
||||
/// The modified pipeline
|
||||
/// </returns>
|
||||
public static MarkdownPipeline UseListExtra(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseListExtra(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<ListExtraExtension>();
|
||||
return pipeline;
|
||||
@@ -279,7 +281,7 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseGenericAttributes(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseGenericAttributes(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<GenericAttributesExtension>();
|
||||
return pipeline;
|
||||
@@ -290,10 +292,31 @@ namespace Markdig
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipeline UseEmojiAndSmiley(this MarkdownPipeline pipeline)
|
||||
public static MarkdownPipelineBuilder UseEmojiAndSmiley(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<EmojiExtension>();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will disable the HTML support in the markdown processor (for constraint/safe parsing).
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipelineBuilder DisableHtml(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
var parser = pipeline.BlockParsers.Find<HtmlBlockParser>();
|
||||
if (parser != null)
|
||||
{
|
||||
pipeline.BlockParsers.Remove(parser);
|
||||
}
|
||||
|
||||
var inlineParser = pipeline.InlineParsers.Find<AutolineInlineParser>();
|
||||
if (inlineParser != null)
|
||||
{
|
||||
inlineParser.EnableHtmlParsing = false;
|
||||
}
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,104 +5,51 @@ using System;
|
||||
using System.IO;
|
||||
using Markdig.Helpers;
|
||||
using Markdig.Parsers;
|
||||
using Markdig.Parsers.Inlines;
|
||||
using Markdig.Renderers;
|
||||
|
||||
namespace Markdig
|
||||
{
|
||||
/// <summary>
|
||||
/// This class allows to modify the pipeline to parse and render a Markdown document.
|
||||
/// This class is the Markdown pipeline build from a <see cref="MarkdownPipelineBuilder"/>.
|
||||
/// </summary>
|
||||
public class MarkdownPipeline
|
||||
{
|
||||
// This class is immutable
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MarkdownPipeline" /> class.
|
||||
/// </summary>
|
||||
public MarkdownPipeline()
|
||||
internal MarkdownPipeline(OrderedList<IMarkdownExtension> extensions, BlockParserList blockParsers, InlineParserList inlineParsers, StringBuilderCache cache, TextWriter debugLog, ProcessDocumentDelegate documentProcessed)
|
||||
{
|
||||
if (blockParsers == null) throw new ArgumentNullException(nameof(blockParsers));
|
||||
if (inlineParsers == null) throw new ArgumentNullException(nameof(inlineParsers));
|
||||
// Add all default parsers
|
||||
BlockParsers = new BlockParserList()
|
||||
{
|
||||
new ThematicBreakParser(),
|
||||
new HeadingBlockParser(),
|
||||
new QuoteBlockParser(),
|
||||
new ListBlockParser(),
|
||||
|
||||
new HtmlBlockParser(),
|
||||
new FencedCodeBlockParser(),
|
||||
new IndentedCodeBlockParser(),
|
||||
new ParagraphBlockParser(),
|
||||
};
|
||||
|
||||
InlineParsers = new InlineParserList()
|
||||
{
|
||||
new HtmlEntityParser(),
|
||||
new LinkInlineParser(),
|
||||
new EscapeInlineParser(),
|
||||
new EmphasisInlineParser(),
|
||||
new CodeInlineParser(),
|
||||
new AutolineInlineParser(),
|
||||
new LineBreakInlineParser(),
|
||||
};
|
||||
|
||||
Extensions = new OrderedList<IMarkdownExtension>();
|
||||
|
||||
Renderer = new HtmlRenderer(new StringWriter());
|
||||
|
||||
StringBuilderCache = new StringBuilderCache();
|
||||
Extensions = extensions;
|
||||
BlockParsers = blockParsers;
|
||||
InlineParsers = inlineParsers;
|
||||
StringBuilderCache = cache;
|
||||
DebugLog = debugLog;
|
||||
DocumentProcessed = documentProcessed;
|
||||
}
|
||||
internal OrderedList<IMarkdownExtension> Extensions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the block parsers.
|
||||
/// </summary>
|
||||
public BlockParserList BlockParsers { get; private set; }
|
||||
internal BlockParserList BlockParsers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the inline parsers.
|
||||
/// </summary>
|
||||
public InlineParserList InlineParsers { get; private set; }
|
||||
internal InlineParserList InlineParsers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the renderer.
|
||||
/// </summary>
|
||||
public IMarkdownRenderer Renderer { get; set; }
|
||||
internal StringBuilderCache StringBuilderCache { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the register extensions.
|
||||
/// </summary>
|
||||
public OrderedList<IMarkdownExtension> Extensions { get; }
|
||||
// TODO: Move the log to a better place
|
||||
internal TextWriter DebugLog { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the string builder cache used by the parsers.
|
||||
/// </summary>
|
||||
public StringBuilderCache StringBuilderCache { get; set; }
|
||||
internal ProcessDocumentDelegate DocumentProcessed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the debug log.
|
||||
/// </summary>
|
||||
public TextWriter DebugLog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a document has been processed after the <see cref="MarkdownParser.Parse"/> method.
|
||||
/// </summary>
|
||||
public event ProcessDocumentDelegate DocumentProcessed;
|
||||
|
||||
internal ProcessDocumentDelegate GetDocumentProcessed => DocumentProcessed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance.
|
||||
/// </summary>
|
||||
/// <exception cref="System.InvalidOperationException">An extension cannot be null</exception>
|
||||
public void Initialize()
|
||||
internal void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
// Allow extensions to modify existing BlockParsers, InlineParsers and Renderer
|
||||
if (renderer == null) throw new ArgumentNullException(nameof(renderer));
|
||||
foreach (var extension in Extensions)
|
||||
{
|
||||
if (extension == null)
|
||||
{
|
||||
throw new InvalidOperationException("An extension cannot be null");
|
||||
}
|
||||
extension.Setup(this);
|
||||
extension.Setup(renderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
118
src/Markdig/MarkdownPipelineBuilder.cs
Normal file
118
src/Markdig/MarkdownPipelineBuilder.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
// 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;
|
||||
using System.IO;
|
||||
using Markdig.Helpers;
|
||||
using Markdig.Parsers;
|
||||
using Markdig.Parsers.Inlines;
|
||||
using Markdig.Renderers;
|
||||
|
||||
namespace Markdig
|
||||
{
|
||||
/// <summary>
|
||||
/// This class allows to modify the pipeline to parse and render a Markdown document.
|
||||
/// </summary>
|
||||
/// <remarks>NOTE: A pipeline is not thread-safe.</remarks>
|
||||
public class MarkdownPipelineBuilder
|
||||
{
|
||||
private MarkdownPipeline pipeline;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MarkdownPipeline" /> class.
|
||||
/// </summary>
|
||||
public MarkdownPipelineBuilder()
|
||||
{
|
||||
// Add all default parsers
|
||||
BlockParsers = new BlockParserList()
|
||||
{
|
||||
new ThematicBreakParser(),
|
||||
new HeadingBlockParser(),
|
||||
new QuoteBlockParser(),
|
||||
new ListBlockParser(),
|
||||
|
||||
new HtmlBlockParser(),
|
||||
new FencedCodeBlockParser(),
|
||||
new IndentedCodeBlockParser(),
|
||||
new ParagraphBlockParser(),
|
||||
};
|
||||
|
||||
InlineParsers = new InlineParserList()
|
||||
{
|
||||
new HtmlEntityParser(),
|
||||
new LinkInlineParser(),
|
||||
new EscapeInlineParser(),
|
||||
new EmphasisInlineParser(),
|
||||
new CodeInlineParser(),
|
||||
new AutolineInlineParser(),
|
||||
new LineBreakInlineParser(),
|
||||
};
|
||||
|
||||
Extensions = new OrderedList<IMarkdownExtension>();
|
||||
|
||||
StringBuilderCache = new StringBuilderCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the block parsers.
|
||||
/// </summary>
|
||||
public BlockParserList BlockParsers { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the inline parsers.
|
||||
/// </summary>
|
||||
public InlineParserList InlineParsers { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the register extensions.
|
||||
/// </summary>
|
||||
public OrderedList<IMarkdownExtension> Extensions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the string builder cache used by the parsers.
|
||||
/// </summary>
|
||||
public StringBuilderCache StringBuilderCache { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the debug log.
|
||||
/// </summary>
|
||||
public TextWriter DebugLog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a document has been processed after the <see cref="MarkdownParser.Parse"/> method.
|
||||
/// </summary>
|
||||
public event ProcessDocumentDelegate DocumentProcessed;
|
||||
|
||||
internal ProcessDocumentDelegate GetDocumentProcessed => DocumentProcessed;
|
||||
|
||||
/// <summary>
|
||||
/// Builds a pipeline from this instance. Once the pipeline is build, it cannot be modified.
|
||||
/// </summary>
|
||||
/// <exception cref="System.InvalidOperationException">An extension cannot be null</exception>
|
||||
public MarkdownPipeline Build()
|
||||
{
|
||||
if (pipeline != null)
|
||||
{
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
// TODO: Review the whole initialization process for extensions
|
||||
// - It does not prevent a user to modify the pipeline after it has been used
|
||||
// - a pipeline is not thread safe.
|
||||
// We should find a proper way to make the pipeline safely modifiable/freezable (PipelineBuilder -> Pipeline)
|
||||
|
||||
// Allow extensions to modify existing BlockParsers, InlineParsers and Renderer
|
||||
foreach (var extension in Extensions)
|
||||
{
|
||||
if (extension == null)
|
||||
{
|
||||
throw new InvalidOperationException("An extension cannot be null");
|
||||
}
|
||||
extension.Setup(this);
|
||||
}
|
||||
|
||||
pipeline = new MarkdownPipeline(new OrderedList<IMarkdownExtension>(Extensions), new BlockParserList(BlockParsers), new InlineParserList(InlineParsers), StringBuilderCache, DebugLog, GetDocumentProcessed);
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
// 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.Collections.Generic;
|
||||
|
||||
namespace Markdig.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
@@ -9,5 +12,19 @@ namespace Markdig.Parsers
|
||||
/// <seealso cref="Markdig.Parsers.ParserList{Markdig.Parsers.BlockParser, Markdig.Parsers.BlockParserState}" />
|
||||
public class BlockParserList : ParserList<BlockParser, BlockProcessor>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BlockParserList"/> class.
|
||||
/// </summary>
|
||||
public BlockParserList()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BlockParserList"/> class.
|
||||
/// </summary>
|
||||
/// <param name="parsers">The parsers.</param>
|
||||
public BlockParserList(IEnumerable<BlockParser> parsers) : base(parsers)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,14 @@ namespace Markdig.Parsers
|
||||
/// <seealso cref="Markdig.Parsers.ParserList{Markdig.Parsers.InlineParser, Markdig.Parsers.InlineParserState}" />
|
||||
public class InlineParserList : ParserList<InlineParser, InlineProcessor>
|
||||
{
|
||||
public InlineParserList()
|
||||
{
|
||||
}
|
||||
|
||||
public InlineParserList(IEnumerable<InlineParser> parsers) : base(parsers)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the registered delimiter processors.
|
||||
/// </summary>
|
||||
|
||||
@@ -18,8 +18,14 @@ namespace Markdig.Parsers.Inlines
|
||||
public AutolineInlineParser()
|
||||
{
|
||||
OpeningCharacters = new[] {'<'};
|
||||
EnableHtmlParsing = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to enable HTML parsing. Default is <c>true</c>
|
||||
/// </summary>
|
||||
public bool EnableHtmlParsing { get; set; }
|
||||
|
||||
public override bool Match(InlineProcessor processor, ref StringSlice slice)
|
||||
{
|
||||
string link;
|
||||
@@ -29,7 +35,7 @@ namespace Markdig.Parsers.Inlines
|
||||
{
|
||||
processor.Inline = new AutolinkInline() {IsEmail = isEmail, Url = link};
|
||||
}
|
||||
else
|
||||
else if (EnableHtmlParsing)
|
||||
{
|
||||
slice = saved;
|
||||
string htmlTag;
|
||||
|
||||
@@ -41,6 +41,23 @@ namespace Markdig.Parsers.Inlines
|
||||
/// </summary>
|
||||
public List<EmphasisDescriptor> EmphasisDescriptors { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this parser is using the specified character as an emphasis delimiter.
|
||||
/// </summary>
|
||||
/// <param name="c">The character to look for.</param>
|
||||
/// <returns><c>true</c> if this parser is using the specified character as an emphasis delimiter; otherwise <c>false</c></returns>
|
||||
public bool HasEmphasisChar(char c)
|
||||
{
|
||||
foreach (var emphasis in EmphasisDescriptors)
|
||||
{
|
||||
if (emphasis.Character == c)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the create emphasis inline delegate (allowing to create a different emphasis inline class)
|
||||
/// </summary>
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace Markdig.Parsers
|
||||
Reader = reader;
|
||||
|
||||
// Initialize the pipeline
|
||||
pipeline.Initialize();
|
||||
var stringBuilderCache = pipeline.StringBuilderCache ?? new StringBuilderCache();
|
||||
|
||||
document = new MarkdownDocument();
|
||||
@@ -59,7 +58,7 @@ namespace Markdig.Parsers
|
||||
DebugLog = pipeline.DebugLog
|
||||
};
|
||||
|
||||
documentProcessed = pipeline.GetDocumentProcessed;
|
||||
documentProcessed = pipeline.DocumentProcessed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,7 +71,7 @@ namespace Markdig.Parsers
|
||||
public static MarkdownDocument Parse(TextReader reader, MarkdownPipeline pipeline = null)
|
||||
{
|
||||
if (reader == null) throw new ArgumentNullException(nameof(reader));
|
||||
pipeline = pipeline ?? new MarkdownPipeline();
|
||||
pipeline = pipeline ?? new MarkdownPipelineBuilder().Build();
|
||||
|
||||
// Perform the parsing
|
||||
var markdownParser = new MarkdownParser(reader, pipeline);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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.
|
||||
|
||||
namespace Markdig.Parsers
|
||||
{
|
||||
/// <summary>
|
||||
@@ -8,7 +9,7 @@ namespace Markdig.Parsers
|
||||
/// </summary>
|
||||
/// <typeparam name="TProcessor">Type of the parser processor</typeparam>
|
||||
/// <seealso cref="Markdig.Parsers.IMarkdownParser{TParserState}" />
|
||||
public class ParserBase<TProcessor> : IMarkdownParser<TProcessor>
|
||||
public abstract class ParserBase<TProcessor> : IMarkdownParser<TProcessor>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the opening characters this parser will be triggered if the character is found.
|
||||
|
||||
@@ -23,6 +23,10 @@ namespace Markdig.Parsers
|
||||
{
|
||||
}
|
||||
|
||||
protected ParserList(IEnumerable<T> parsers) : base(parsers)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of global parsers (that don't have any opening characters defined)
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
@@ -20,8 +18,13 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
||||
[assembly: AssemblyVersion("0.1.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.1.0.0")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Scriban.Tests")]
|
||||
[assembly: AssemblyVersion(Markdig.Markdown.Version)]
|
||||
[assembly: AssemblyFileVersion(Markdig.Markdown.Version)]
|
||||
|
||||
namespace Markdig
|
||||
{
|
||||
public static partial class Markdown
|
||||
{
|
||||
public const string Version = "0.2.1";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"title": "Markdig",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.1",
|
||||
"authors": [ "Alexandre Mutel" ],
|
||||
"description": "A fast, powerfull, CommonMark compliant, extensible Markdown processor for .NET",
|
||||
"copyright": "Alexandre Mutel",
|
||||
@@ -10,7 +10,8 @@
|
||||
"licenseUrl": "https://github.com/lunet-io/markdig/blob/master/license.txt",
|
||||
"projectUrl": "https://github.com/lunet-io/markdig",
|
||||
"requireLicenseAcceptance": false,
|
||||
"tags": [ "Markdown CommonMark md html" ]
|
||||
"releaseNotes": "Add Markdown.Version",
|
||||
"tags": [ "Markdown CommonMark md html md2html" ]
|
||||
},
|
||||
"configurations": {
|
||||
"Debug": {
|
||||
@@ -28,9 +29,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"NETStandard.Library": "1.5.0-rc2-24027"
|
||||
},
|
||||
"frameworks": {
|
||||
"net35": {
|
||||
"buildOptions": {
|
||||
@@ -61,6 +59,7 @@
|
||||
},
|
||||
"netstandard1.1": {
|
||||
"dependencies": {
|
||||
"NETStandard.Library": "1.5.0-rc2-24027",
|
||||
"System.Threading": "4.0.11-rc2-24027",
|
||||
"System.Threading.Tasks": "4.0.11-rc2-24027",
|
||||
"System.Threading.Tasks.Parallel": "4.0.1-rc2-24027"
|
||||
|
||||
Reference in New Issue
Block a user