mirror of
https://github.com/xoofx/markdig.git
synced 2026-02-15 05:55:41 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3821bd00fe | ||
|
|
62701fd0f1 | ||
|
|
1be5e60506 | ||
|
|
c9f1512358 | ||
|
|
8f23aed6af | ||
|
|
6a62ae9c69 | ||
|
|
2c3de5688b | ||
|
|
f3c08b4ec4 | ||
|
|
69e3baafe5 | ||
|
|
5844ccc395 | ||
|
|
be9c6fa54b | ||
|
|
d14f277c7b | ||
|
|
593bf08b92 |
@@ -214,6 +214,76 @@ Column delimiters `|` at the very beginning of a line or just before a line endi
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
|
||||
A pipe may be present at both the beginning/ending of each line:
|
||||
|
||||
```````````````````````````````` example
|
||||
|a|b|
|
||||
|-|-|
|
||||
|0|1|
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>a</th>
|
||||
<th>b</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>0</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
|
||||
Or may be ommitted on one side:
|
||||
|
||||
```````````````````````````````` example
|
||||
a|b|
|
||||
-|-|
|
||||
0|1|
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>a</th>
|
||||
<th>b</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>0</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
|
||||
```````````````````````````````` example
|
||||
|a|b
|
||||
|-|-
|
||||
|0|1
|
||||
.
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>a</th>
|
||||
<th>b</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>0</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
````````````````````````````````
|
||||
|
||||
|
||||
|
||||
Single column table can be declared with lines starting only by a column delimiter:
|
||||
|
||||
```````````````````````````````` example
|
||||
|
||||
@@ -16631,7 +16631,7 @@ namespace Markdig.Tests
|
||||
TestParser.TestSpec(" a | b |\n-- | --\n| 0 | 1\n| 2 | 3 |\n 4 | 5 ", "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>1</td>\n</tr>\n<tr>\n<td>2</td>\n<td>3</td>\n</tr>\n<tr>\n<td>4</td>\n<td>5</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
// Single column table can be declared with lines starting only by a column delimiter:
|
||||
// A pipe may be present at both the beginning/ending of each line:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
@@ -16642,6 +16642,110 @@ namespace Markdig.Tests
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
// |a|b|
|
||||
// |-|-|
|
||||
// |0|1|
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>a</th>
|
||||
// <th>b</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>0</td>
|
||||
// <td>1</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 10, "Extensions Pipe Table");
|
||||
TestParser.TestSpec("|a|b|\n|-|-|\n|0|1|", "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
// Or may be ommitted on one side:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
// a|b|
|
||||
// -|-|
|
||||
// 0|1|
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>a</th>
|
||||
// <th>b</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>0</td>
|
||||
// <td>1</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 11, "Extensions Pipe Table");
|
||||
TestParser.TestSpec("a|b|\n-|-|\n0|1|", "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example012()
|
||||
{
|
||||
// Example 12
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
// |a|b
|
||||
// |-|-
|
||||
// |0|1
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <table>
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th>a</th>
|
||||
// <th>b</th>
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <td>0</td>
|
||||
// <td>1</td>
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 12, "Extensions Pipe Table");
|
||||
TestParser.TestSpec("|a|b\n|-|-\n|0|1", "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
// Single column table can be declared with lines starting only by a column delimiter:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example013()
|
||||
{
|
||||
// Example 13
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
// | a
|
||||
// | --
|
||||
// | b
|
||||
@@ -16664,7 +16768,7 @@ namespace Markdig.Tests
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 10, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 13, "Extensions Pipe Table");
|
||||
TestParser.TestSpec("| a\n| --\n| b\n| c ", "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n<tr>\n<td>c</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -16681,9 +16785,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example011()
|
||||
public void Example014()
|
||||
{
|
||||
// Example 11
|
||||
// Example 14
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -16712,7 +16816,7 @@ namespace Markdig.Tests
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 11, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 14, "Extensions Pipe Table");
|
||||
TestParser.TestSpec(" a | b \n-------|-------\n 0 | 1 \n 2 | 3 ", "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>1</td>\n</tr>\n<tr>\n<td>2</td>\n<td>3</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -16722,9 +16826,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example012()
|
||||
public void Example015()
|
||||
{
|
||||
// Example 12
|
||||
// Example 15
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -16756,7 +16860,7 @@ namespace Markdig.Tests
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 12, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 15, "Extensions Pipe Table");
|
||||
TestParser.TestSpec(" a | b | c \n:------|:-------:| ----:\n 0 | 1 | 2 \n 3 | 4 | 5 ", "<table>\n<thead>\n<tr>\n<th>a</th>\n<th style=\"text-align: center;\">b</th>\n<th style=\"text-align: right;\">c</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td style=\"text-align: center;\">1</td>\n<td style=\"text-align: right;\">2</td>\n</tr>\n<tr>\n<td>3</td>\n<td style=\"text-align: center;\">4</td>\n<td style=\"text-align: right;\">5</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -16765,9 +16869,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example013()
|
||||
public void Example016()
|
||||
{
|
||||
// Example 13
|
||||
// Example 16
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -16782,7 +16886,7 @@ namespace Markdig.Tests
|
||||
// 0 | 1
|
||||
// 2 | 3</p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 13, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 16, "Extensions Pipe Table");
|
||||
TestParser.TestSpec(" a | b\n-------|---x---\n 0 | 1\n 2 | 3 ", "<p>a | b\n-------|---x---\n0 | 1\n2 | 3</p> ", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -16793,9 +16897,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example014()
|
||||
public void Example017()
|
||||
{
|
||||
// Example 14
|
||||
// Example 17
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -16824,7 +16928,7 @@ namespace Markdig.Tests
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 14, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 17, "Extensions Pipe Table");
|
||||
TestParser.TestSpec(" *a* | b\n----- |-----\n 0 | _1_\n _2 | 3* ", "<table>\n<thead>\n<tr>\n<th><em>a</em></th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td><em>1</em></td>\n</tr>\n<tr>\n<td>_2</td>\n<td>3*</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -16835,9 +16939,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example015()
|
||||
public void Example018()
|
||||
{
|
||||
// Example 15
|
||||
// Example 18
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -16847,7 +16951,7 @@ namespace Markdig.Tests
|
||||
// Should be rendered as:
|
||||
// <p>a | b <code>0 |</code></p>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 15, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 18, "Extensions Pipe Table");
|
||||
TestParser.TestSpec("a | b `\n0 | ` ", "<p>a | b <code>0 |</code></p> ", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -16858,9 +16962,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example016()
|
||||
public void Example019()
|
||||
{
|
||||
// Example 16
|
||||
// Example 19
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -16884,7 +16988,7 @@ namespace Markdig.Tests
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 16, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 19, "Extensions Pipe Table");
|
||||
TestParser.TestSpec("a <a href=\"\" title=\"|\"></a> | b\n-- | --\n0 | 1", "<table>\n<thead>\n<tr>\n<th>a <a href=\"\" title=\"|\"></a></th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>1</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -16895,9 +16999,9 @@ namespace Markdig.Tests
|
||||
public partial class TestExtensionsPipeTable
|
||||
{
|
||||
[Test]
|
||||
public void Example017()
|
||||
public void Example020()
|
||||
{
|
||||
// Example 17
|
||||
// Example 20
|
||||
// Section: Extensions Pipe Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
@@ -16921,7 +17025,7 @@ namespace Markdig.Tests
|
||||
// </tbody>
|
||||
// </table>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 17, "Extensions Pipe Table");
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 20, "Extensions Pipe Table");
|
||||
TestParser.TestSpec("a | b\n-- | --\n[This is a link with a | inside the label](http://google.com) | 1", "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><a href=\"http://google.com\">This is a link with a | inside the label</a></td>\n<td>1</td>\n</tr>\n</tbody>\n</table>", "pipetables");
|
||||
}
|
||||
}
|
||||
@@ -19213,15 +19317,15 @@ namespace Markdig.Tests
|
||||
// - Item4
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ul>
|
||||
// <li><input disabled="disabled" type="checkbox" /> Item1</li>
|
||||
// <li><input disabled="disabled" type="checkbox" checked="checked" /> Item2</li>
|
||||
// <li><input disabled="disabled" type="checkbox" /> Item3</li>
|
||||
// <ul class="contains-task-list">
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" /> Item1</li>
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Item2</li>
|
||||
// <li class="task-list-item"><input disabled="disabled" type="checkbox" /> Item3</li>
|
||||
// <li>Item4</li>
|
||||
// </ul>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 1, "Extensions TaskLists");
|
||||
TestParser.TestSpec("- [ ] Item1\n- [x] Item2\n- [ ] Item3\n- Item4", "<ul>\n<li><input disabled=\"disabled\" type=\"checkbox\" /> Item1</li>\n<li><input disabled=\"disabled\" type=\"checkbox\" checked=\"checked\" /> Item2</li>\n<li><input disabled=\"disabled\" type=\"checkbox\" /> Item3</li>\n<li>Item4</li>\n</ul>", "tasklists");
|
||||
TestParser.TestSpec("- [ ] Item1\n- [x] Item2\n- [ ] Item3\n- Item4", "<ul class=\"contains-task-list\">\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" /> Item1</li>\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" checked=\"checked\" /> Item2</li>\n<li class=\"task-list-item\"><input disabled=\"disabled\" type=\"checkbox\" /> Item3</li>\n<li>Item4</li>\n</ul>", "tasklists");
|
||||
}
|
||||
}
|
||||
// A task is not recognized outside a list item:
|
||||
|
||||
@@ -12,10 +12,10 @@ A task list item consist of `[ ]` or `[x]` or `[X]` inside a list item (ordered
|
||||
- [ ] Item3
|
||||
- Item4
|
||||
.
|
||||
<ul>
|
||||
<li><input disabled="disabled" type="checkbox" /> Item1</li>
|
||||
<li><input disabled="disabled" type="checkbox" checked="checked" /> Item2</li>
|
||||
<li><input disabled="disabled" type="checkbox" /> Item3</li>
|
||||
<ul class="contains-task-list">
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" /> Item1</li>
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" checked="checked" /> Item2</li>
|
||||
<li class="task-list-item"><input disabled="disabled" type="checkbox" /> Item3</li>
|
||||
<li>Item4</li>
|
||||
</ul>
|
||||
````````````````````````````````
|
||||
|
||||
@@ -206,19 +206,6 @@ literal ( 0, 4) 4-5
|
||||
Assert.AreEqual(SourceSpan.Empty, link.TitleSpan);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHtmlInline()
|
||||
{
|
||||
// 0123456789
|
||||
Check("01<b>4</b>", @"
|
||||
paragraph ( 0, 0) 0-9
|
||||
literal ( 0, 0) 0-1
|
||||
html ( 0, 2) 2-4
|
||||
literal ( 0, 5) 5-5
|
||||
html ( 0, 6) 6-9
|
||||
");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAutolinkInline()
|
||||
{
|
||||
@@ -252,6 +239,64 @@ literal ( 4, 0) 16-16
|
||||
");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHtmlBlock1()
|
||||
{
|
||||
// 0 1
|
||||
// 01 2 345678901 23
|
||||
Check("0\n\n<!--A-->\n1\n", @"
|
||||
paragraph ( 0, 0) 0-0
|
||||
literal ( 0, 0) 0-0
|
||||
html ( 2, 0) 3-10
|
||||
paragraph ( 3, 0) 12-12
|
||||
literal ( 3, 0) 12-12
|
||||
");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHtmlComment()
|
||||
{
|
||||
// 0 1 2
|
||||
// 012345678901 234567890 1234
|
||||
Check("# 012345678\n<!--0-->\n123\n", @"
|
||||
heading ( 0, 0) 0-10
|
||||
literal ( 0, 2) 2-10
|
||||
html ( 1, 0) 12-19
|
||||
paragraph ( 2, 0) 21-23
|
||||
literal ( 2, 0) 21-23
|
||||
");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHtmlInline()
|
||||
{
|
||||
// 0123456789
|
||||
Check("01<b>4</b>", @"
|
||||
paragraph ( 0, 0) 0-9
|
||||
literal ( 0, 0) 0-1
|
||||
html ( 0, 2) 2-4
|
||||
literal ( 0, 5) 5-5
|
||||
html ( 0, 6) 6-9
|
||||
");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHtmlInline1()
|
||||
{
|
||||
// 0
|
||||
// 0123456789
|
||||
Check("0<!--A-->1", @"
|
||||
paragraph ( 0, 0) 0-9
|
||||
literal ( 0, 0) 0-0
|
||||
html ( 0, 1) 1-8
|
||||
literal ( 0, 9) 9-9
|
||||
");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestThematicBreak()
|
||||
{
|
||||
|
||||
79
src/Markdig/Extensions/PragmaLines/PragmaLineExtension.cs
Normal file
79
src/Markdig/Extensions/PragmaLines/PragmaLineExtension.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
// 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 Markdig.Helpers;
|
||||
using Markdig.Renderers;
|
||||
using Markdig.Renderers.Html;
|
||||
using Markdig.Syntax;
|
||||
using Markdig.Syntax.Inlines;
|
||||
|
||||
namespace Markdig.Extensions.PragmaLines
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension to a span for each line containing the original line id (using id = pragma-line#line_number_zero_based)
|
||||
/// </summary>
|
||||
/// <seealso cref="Markdig.IMarkdownExtension" />
|
||||
public class PragmaLineExtension : IMarkdownExtension
|
||||
{
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.DocumentProcessed -= PipelineOnDocumentProcessed;
|
||||
pipeline.DocumentProcessed += PipelineOnDocumentProcessed;
|
||||
}
|
||||
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
}
|
||||
|
||||
private static void PipelineOnDocumentProcessed(MarkdownDocument document)
|
||||
{
|
||||
int index = 0;
|
||||
AddPragmas(document, ref index);
|
||||
}
|
||||
|
||||
private static void AddPragmas(Block block, ref int index)
|
||||
{
|
||||
var attribute = block.GetAttributes();
|
||||
var pragmaId = GetPragmaId(block);
|
||||
if ( attribute.Id == null)
|
||||
{
|
||||
attribute.Id = pragmaId;
|
||||
}
|
||||
else if (block.Parent != null)
|
||||
{
|
||||
var heading = block as HeadingBlock;
|
||||
|
||||
// If we have a heading, we will try to add the tag inside it
|
||||
// otherwise we will add it just before
|
||||
var tag = $"<a id=\"{pragmaId}\"></a>";
|
||||
if (heading?.Inline?.FirstChild != null)
|
||||
{
|
||||
heading.Inline.FirstChild.InsertBefore(new HtmlInline() { Tag = tag });
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
block.Parent.Insert(index, new HtmlBlock(null) { Lines = new StringLineGroup(tag) });
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
var container = block as ContainerBlock;
|
||||
if (container != null)
|
||||
{
|
||||
for (int i = 0; i < container.Count; i++)
|
||||
{
|
||||
var subBlock = container[i];
|
||||
AddPragmas(subBlock, ref i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetPragmaId(Block block)
|
||||
{
|
||||
return $"pragma-line-{block.Line}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,8 @@ namespace Markdig.Extensions.Tables
|
||||
|
||||
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
// Pipe tables require precise source location
|
||||
pipeline.PreciseSourceLocation = true;
|
||||
if (!pipeline.BlockParsers.Contains<PipeTableBlockParser>())
|
||||
{
|
||||
pipeline.BlockParsers.Insert(0, new PipeTableBlockParser());
|
||||
|
||||
@@ -444,8 +444,8 @@ namespace Markdig.Extensions.Tables
|
||||
}
|
||||
|
||||
// Check the left side of a `|` delimiter
|
||||
TableColumnAlign align;
|
||||
if (!ParseHeaderString(delimiter.PreviousSibling, out align))
|
||||
TableColumnAlign align = TableColumnAlign.Left;
|
||||
if (delimiter.PreviousSibling != null && !ParseHeaderString(delimiter.PreviousSibling, out align))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the license.txt file in the project root for more information.
|
||||
using Markdig.Helpers;
|
||||
using Markdig.Parsers;
|
||||
using Markdig.Renderers.Html;
|
||||
using Markdig.Syntax;
|
||||
|
||||
namespace Markdig.Extensions.TaskLists
|
||||
@@ -18,15 +19,29 @@ namespace Markdig.Extensions.TaskLists
|
||||
public TaskListInlineParser()
|
||||
{
|
||||
OpeningCharacters = new[] {'['};
|
||||
ListClass = "contains-task-list";
|
||||
ListItemClass = "task-list-item";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list class used for a task list.
|
||||
/// </summary>
|
||||
public string ListClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list item class used for a task list.
|
||||
/// </summary>
|
||||
public string ListItemClass { get; set; }
|
||||
|
||||
public override bool Match(InlineProcessor processor, ref StringSlice slice)
|
||||
{
|
||||
// A tasklist is either
|
||||
// [ ]
|
||||
// or [x] or [X]
|
||||
|
||||
if (!(processor.Block.Parent is ListItemBlock))
|
||||
var listItemBlock = processor.Block.Parent as ListItemBlock;
|
||||
|
||||
if (listItemBlock == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -56,6 +71,19 @@ namespace Markdig.Extensions.TaskLists
|
||||
};
|
||||
taskItem.Span.End = taskItem.Span.Start + 2;
|
||||
processor.Inline = taskItem;
|
||||
|
||||
// Add proper class for task list
|
||||
if (!string.IsNullOrEmpty(ListItemClass))
|
||||
{
|
||||
listItemBlock.GetAttributes().AddClass(ListItemClass);
|
||||
}
|
||||
|
||||
var listBlock = (ListBlock) listItemBlock.Parent;
|
||||
if (!string.IsNullOrEmpty(ListClass))
|
||||
{
|
||||
listBlock.GetAttributes().AddClass(ListClass);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace Markdig.Helpers
|
||||
index = Start + offset;
|
||||
for (int i = index; i <= end; i ++)
|
||||
{
|
||||
if (Match(text, End, i))
|
||||
if (Match(text, End, i - Start))
|
||||
{
|
||||
index = i + text.Length;
|
||||
return true;
|
||||
|
||||
@@ -30,13 +30,14 @@ namespace Markdig
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Markdown string to HTML.
|
||||
/// Converts a Markdown string to HTML and output to the specified writer.
|
||||
/// </summary>
|
||||
/// <param name="markdown">A Markdown text.</param>
|
||||
/// <param name="writer">The destination <see cref="TextWriter"/> that will receive the result of the conversion.</param>
|
||||
/// <param name="pipeline">The pipeline used for the conversion.</param>
|
||||
/// <returns>The Markdown document that has been parsed</returns>
|
||||
/// <exception cref="System.ArgumentNullException">if reader or writer variable are null</exception>
|
||||
public static void ToHtml(string markdown, TextWriter writer, MarkdownPipeline pipeline = null)
|
||||
public static MarkdownDocument ToHtml(string markdown, TextWriter writer, MarkdownPipeline pipeline = null)
|
||||
{
|
||||
if (markdown == null) throw new ArgumentNullException(nameof(markdown));
|
||||
if (writer == null) throw new ArgumentNullException(nameof(writer));
|
||||
@@ -49,6 +50,8 @@ namespace Markdig
|
||||
var document = Parse(markdown, pipeline);
|
||||
renderer.Render(document);
|
||||
writer.Flush();
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -19,6 +19,7 @@ using Markdig.Extensions.Hardlines;
|
||||
using Markdig.Extensions.ListExtras;
|
||||
using Markdig.Extensions.Mathematics;
|
||||
using Markdig.Extensions.MediaLinks;
|
||||
using Markdig.Extensions.PragmaLines;
|
||||
using Markdig.Extensions.SmartyPants;
|
||||
using Markdig.Extensions.Tables;
|
||||
using Markdig.Extensions.TaskLists;
|
||||
@@ -58,6 +59,17 @@ namespace Markdig
|
||||
.UseGenericAttributes(); // Must be last as it is one parser that is modifying other parsers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses pragma lines to output span with an id containing the line number (pragma-line#line_number_zero_based`)
|
||||
/// </summary>
|
||||
/// <param name="pipeline">The pipeline.</param>
|
||||
/// <returns>The modified pipeline</returns>
|
||||
public static MarkdownPipelineBuilder UsePragmaLines(this MarkdownPipelineBuilder pipeline)
|
||||
{
|
||||
pipeline.Extensions.AddIfNotAlready<PragmaLineExtension>();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses precise source code location (useful for syntax highlighting).
|
||||
/// </summary>
|
||||
|
||||
@@ -47,7 +47,11 @@ namespace Markdig
|
||||
|
||||
internal ProcessDocumentDelegate DocumentProcessed;
|
||||
|
||||
internal void Setup(IMarkdownRenderer renderer)
|
||||
/// <summary>
|
||||
/// Allows to setup a <see cref="IMarkdownRenderer"/>.
|
||||
/// </summary>
|
||||
/// <param name="renderer">The markdown renderer to setup</param>
|
||||
public void Setup(IMarkdownRenderer renderer)
|
||||
{
|
||||
if (renderer == null) throw new ArgumentNullException(nameof(renderer));
|
||||
foreach (var extension in Extensions)
|
||||
|
||||
@@ -25,6 +25,6 @@ namespace Markdig
|
||||
{
|
||||
public static partial class Markdown
|
||||
{
|
||||
public const string Version = "0.5.2";
|
||||
public const string Version = "0.5.6";
|
||||
}
|
||||
}
|
||||
@@ -44,9 +44,14 @@ namespace Markdig.Renderers.Html
|
||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
||||
if (Classes == null)
|
||||
{
|
||||
Classes = new List<string>(2); // Use half list compare to default capacity (4), as we don't expect lots of classes
|
||||
Classes = new List<string>(2);
|
||||
// Use half list compare to default capacity (4), as we don't expect lots of classes
|
||||
}
|
||||
|
||||
if (!Classes.Contains(name))
|
||||
{
|
||||
Classes.Add(name);
|
||||
}
|
||||
Classes.Add(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -32,7 +32,9 @@ namespace Markdig.Renderers.Html
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer.WriteLine("<ul>");
|
||||
renderer.Write("<ul");
|
||||
renderer.WriteAttributes(listBlock);
|
||||
renderer.WriteLine(">");
|
||||
}
|
||||
foreach (var item in listBlock)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
using Markdig.Syntax;
|
||||
using Markdig.Syntax.Inlines;
|
||||
|
||||
@@ -11,6 +13,16 @@ namespace Markdig.Renderers
|
||||
/// </summary>
|
||||
public interface IMarkdownRenderer
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when before writing an object.
|
||||
/// </summary>
|
||||
event Action<IMarkdownRenderer, MarkdownObject> ObjectWriteBefore;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when after writing an object.
|
||||
/// </summary>
|
||||
event Action<IMarkdownRenderer, MarkdownObject> ObjectWriteAfter;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the object renderers that will render <see cref="Block"/> and <see cref="Inline"/> elements.
|
||||
/// </summary>
|
||||
|
||||
@@ -35,6 +35,16 @@ namespace Markdig.Renderers
|
||||
|
||||
public bool IsLastInContainer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when before writing an object.
|
||||
/// </summary>
|
||||
public event Action<IMarkdownRenderer, MarkdownObject> ObjectWriteBefore;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when after writing an object.
|
||||
/// </summary>
|
||||
public event Action<IMarkdownRenderer, MarkdownObject> ObjectWriteAfter;
|
||||
|
||||
/// <summary>
|
||||
/// Writes the children of the specified <see cref="ContainerBlock"/>.
|
||||
/// </summary>
|
||||
@@ -105,6 +115,10 @@ namespace Markdig.Renderers
|
||||
|
||||
var objectType = obj.GetType();
|
||||
|
||||
// Calls before writing an object
|
||||
var writeBefore = ObjectWriteBefore;
|
||||
writeBefore?.Invoke(this, obj);
|
||||
|
||||
// Handle regular renderers
|
||||
IMarkdownObjectRenderer renderer = previousObjectType == objectType ? previousRenderer : null;
|
||||
if (renderer == null && !renderersPerType.TryGetValue(objectType, out renderer))
|
||||
@@ -142,6 +156,10 @@ namespace Markdig.Renderers
|
||||
|
||||
previousObjectType = objectType;
|
||||
previousRenderer = renderer;
|
||||
|
||||
// Calls after writing an object
|
||||
var writeAfter = ObjectWriteAfter;
|
||||
writeAfter?.Invoke(this, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"title": "Markdig",
|
||||
"version": "0.5.2",
|
||||
"version": "0.5.6",
|
||||
"authors": [ "Alexandre Mutel" ],
|
||||
"description": "A fast, powerfull, CommonMark compliant, extensible Markdown processor for .NET",
|
||||
"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.5.2:\nAdd better support for precise source location for link parts (label, url...)\n> 0.5.1:\nAdd support for task lists.\nAdd support for precise source location pipelineBuilder.UsePreciseSourceLocation.\nBreaking change: Markdown.ToHtml() accept now only a string instead of a TextReader as this improve the overall performance.",
|
||||
"releaseNotes": ">0.5.6\n- Improve pragma line output\n- Make MarkdownPipeline.Setup(renderer) public.\n> 0.5.5\n- Add same github class for task lists\n- Add pragma lines extension\n> 0.5.4:\nFix bug in HTML block parsing which could break parsing of remaining document",
|
||||
"tags": [ "Markdown CommonMark md html md2html" ]
|
||||
},
|
||||
"configurations": {
|
||||
|
||||
Reference in New Issue
Block a user