mirror of
https://github.com/xoofx/markdig.git
synced 2026-02-14 05:45:05 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d5980a485 | ||
|
|
19dd902519 | ||
|
|
f046a46275 | ||
|
|
25e9eafa8b | ||
|
|
f4ff981008 |
@@ -272,4 +272,15 @@ A grid table may not have irregularly shaped cells:
|
||||
+---+---+---+
|
||||
| DDDDD | E |
|
||||
+---+---+---+</p>
|
||||
````````````````````````````````
|
||||
````````````````````````````````
|
||||
|
||||
An empty `+` on a line should result in a simple empty list output:
|
||||
|
||||
|
||||
```````````````````````````````` example
|
||||
+
|
||||
.
|
||||
<ul>
|
||||
<li></li>
|
||||
</ul>
|
||||
````````````````````````````````
|
||||
|
||||
@@ -17994,6 +17994,28 @@ namespace Markdig.Tests
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 10, "Extensions Grid Table");
|
||||
TestParser.TestSpec("+---+---+---+\n| AAAAA | B |\n+ A +---+ B +\n| A | C | B |\n+---+---+---+\n| DDDDD | E |\n+---+---+---+", "<p>+---+---+---+\n| AAAAA | B |\n+ A +---+ B +\n| A | C | B |\n+---+---+---+\n| DDDDD | E |\n+---+---+---+</p>", "gridtables|advanced");
|
||||
}
|
||||
}
|
||||
// An empty `+` on a line should result in a simple empty list output:
|
||||
[TestFixture]
|
||||
public partial class TestExtensionsGridTable
|
||||
{
|
||||
[Test]
|
||||
public void Example011()
|
||||
{
|
||||
// Example 11
|
||||
// Section: Extensions Grid Table
|
||||
//
|
||||
// The following CommonMark:
|
||||
// +
|
||||
//
|
||||
// Should be rendered as:
|
||||
// <ul>
|
||||
// <li></li>
|
||||
// </ul>
|
||||
|
||||
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 11, "Extensions Grid Table");
|
||||
TestParser.TestSpec("+", "<ul>\n<li></li>\n</ul>", "gridtables|advanced");
|
||||
}
|
||||
}
|
||||
// # Extensions
|
||||
//
|
||||
|
||||
@@ -15,25 +15,30 @@ namespace Markdig.Tests
|
||||
foreach (var pipeline in GetPipeline(extensions))
|
||||
{
|
||||
Console.WriteLine($"Pipeline configured with extensions: {pipeline.Key}");
|
||||
// Uncomment this line to get more debug information for process inlines.
|
||||
//pipeline.DebugLog = Console.Out;
|
||||
var result = Markdown.ToHtml(inputText, pipeline.Value);
|
||||
|
||||
result = Compact(result);
|
||||
expectedOutputText = Compact(expectedOutputText);
|
||||
|
||||
Console.WriteLine("```````````````````Source");
|
||||
Console.WriteLine(DisplaySpaceAndTabs(inputText));
|
||||
Console.WriteLine("```````````````````Result");
|
||||
Console.WriteLine(DisplaySpaceAndTabs(result));
|
||||
Console.WriteLine("```````````````````Expected");
|
||||
Console.WriteLine(DisplaySpaceAndTabs(expectedOutputText));
|
||||
Console.WriteLine("```````````````````");
|
||||
Console.WriteLine();
|
||||
TextAssert.AreEqual(expectedOutputText, result);
|
||||
TestSpec(inputText, expectedOutputText, pipeline.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void TestSpec(string inputText, string expectedOutputText, MarkdownPipeline pipeline)
|
||||
{
|
||||
// Uncomment this line to get more debug information for process inlines.
|
||||
//pipeline.DebugLog = Console.Out;
|
||||
var result = Markdown.ToHtml(inputText, pipeline);
|
||||
|
||||
result = Compact(result);
|
||||
expectedOutputText = Compact(expectedOutputText);
|
||||
|
||||
Console.WriteLine("```````````````````Source");
|
||||
Console.WriteLine(DisplaySpaceAndTabs(inputText));
|
||||
Console.WriteLine("```````````````````Result");
|
||||
Console.WriteLine(DisplaySpaceAndTabs(result));
|
||||
Console.WriteLine("```````````````````Expected");
|
||||
Console.WriteLine(DisplaySpaceAndTabs(expectedOutputText));
|
||||
Console.WriteLine("```````````````````");
|
||||
Console.WriteLine();
|
||||
TextAssert.AreEqual(expectedOutputText, result);
|
||||
}
|
||||
|
||||
private static IEnumerable<KeyValuePair<string, MarkdownPipeline>> GetPipeline(string extensionsGroupText)
|
||||
{
|
||||
// For the standard case, we make sure that both the CommmonMark core and Extra/Advanced are CommonMark compliant!
|
||||
|
||||
@@ -659,6 +659,20 @@ code ( 2, 0) 3-13
|
||||
");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIndentedCodeAfterList()
|
||||
{
|
||||
// 0 1 2 3 4 5
|
||||
// 012345678901234567 8 901234567890123456 789012345678901234 56789
|
||||
Check("1) Some list item\n\n some code\n more code\n", @"
|
||||
list ( 0, 0) 0-53
|
||||
listitem ( 0, 0) 0-53
|
||||
paragraph ( 0, 3) 3-16
|
||||
literal ( 0, 3) 3-16
|
||||
code ( 2, 0) 19-53
|
||||
");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIndentedCodeWithTabs()
|
||||
{
|
||||
|
||||
@@ -27,32 +27,36 @@ namespace Markdig.Extensions.Tables
|
||||
var line = processor.Line;
|
||||
GridTableState tableState = null;
|
||||
|
||||
// Match the first row that should be of the minimal form: +---------------
|
||||
var c = line.CurrentChar;
|
||||
var lineStart = line.Start;
|
||||
int startPosition = -1;
|
||||
bool hasLeft = false,
|
||||
hasRight = false;
|
||||
|
||||
while (line.Length > 0)
|
||||
while (c == '+')
|
||||
{
|
||||
if (c == '+')
|
||||
var columnStart = line.Start;
|
||||
line.NextChar();
|
||||
line.TrimStart();
|
||||
|
||||
// if we have reached the end of the line, exit
|
||||
c = line.CurrentChar;
|
||||
if (c == 0)
|
||||
{
|
||||
tableState = tableState ?? new GridTableState { Start = processor.Start, ExpectRow = true };
|
||||
if (startPosition != -1)
|
||||
{
|
||||
hasRight = line.PeekCharAbsolute(line.Start - 1) == ':';
|
||||
tableState.AddColumn(startPosition - lineStart, line.Start - lineStart, GetAlignment(hasLeft, hasRight));
|
||||
}
|
||||
hasLeft = line.PeekChar(1) == ':';
|
||||
startPosition = line.Start;
|
||||
break;
|
||||
}
|
||||
else if (c != ':' && c != '-')
|
||||
|
||||
// Parse a column alignment
|
||||
TableColumnAlign columnAlign;
|
||||
if (!TableHelper.ParseColumnHeader(ref line, '-', out columnAlign))
|
||||
{
|
||||
return BlockState.None;
|
||||
}
|
||||
c = line.NextChar();
|
||||
|
||||
tableState = tableState ?? new GridTableState { Start = processor.Start, ExpectRow = true };
|
||||
tableState.AddColumn(columnStart - lineStart, line.Start - lineStart, columnAlign);
|
||||
|
||||
c = line.CurrentChar;
|
||||
}
|
||||
if (tableState == null || tableState.ColumnSlices.Count == (processor.Line.Length - 1))
|
||||
|
||||
if (c != 0 || tableState == null)
|
||||
{
|
||||
return BlockState.None;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace Markdig.Extensions.Tables
|
||||
{
|
||||
align = TableColumnAlign.Left;
|
||||
|
||||
// Work on a copy of the slice
|
||||
slice.TrimStart();
|
||||
var c = slice.CurrentChar;
|
||||
bool hasLeft = false;
|
||||
@@ -87,6 +86,7 @@ namespace Markdig.Extensions.Tables
|
||||
count++;
|
||||
}
|
||||
|
||||
// We expect at least one `-` delimiter char
|
||||
if (count == 0)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -304,6 +304,64 @@ namespace Markdig.Parsers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unwind any previous indent from the current character back to the first space.
|
||||
/// </summary>
|
||||
public void UnwindAllIndents()
|
||||
{
|
||||
// Find the previous first space on the current line
|
||||
var previousStart = Line.Start;
|
||||
for (; Line.Start > originalLineStart; Line.Start--)
|
||||
{
|
||||
var c = Line.PeekCharAbsolute(Line.Start - 1);
|
||||
if (c == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!c.IsSpaceOrTab())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
var targetStart = Line.Start;
|
||||
// Nothing changed? Early exit
|
||||
if (previousStart == targetStart)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: factorize the following code with what is done with GoToColumn
|
||||
|
||||
// If we have found the first space, we need to recalculate the correct column
|
||||
Line.Start = originalLineStart;
|
||||
Column = 0;
|
||||
ColumnBeforeIndent = 0;
|
||||
StartBeforeIndent = originalLineStart;
|
||||
|
||||
for (; Line.Start < targetStart; Line.Start++)
|
||||
{
|
||||
var c = Line.Text[Line.Start];
|
||||
if (c == '\t')
|
||||
{
|
||||
Column = CharHelper.AddTab(Column);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!c.IsSpaceOrTab())
|
||||
{
|
||||
ColumnBeforeIndent = Column + 1;
|
||||
StartBeforeIndent = Line.Start + 1;
|
||||
}
|
||||
|
||||
Column++;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the indent
|
||||
ColumnBeforeIndent = Column;
|
||||
StartBeforeIndent = Start;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves to the position to the code indent (<see cref="ColumnBeforeIndent"/> + 4 spaces).
|
||||
/// </summary>
|
||||
|
||||
@@ -18,16 +18,23 @@ namespace Markdig.Parsers
|
||||
|
||||
public override BlockState TryOpen(BlockProcessor processor)
|
||||
{
|
||||
var startColumn = processor.ColumnBeforeIndent;
|
||||
var startPosition = processor.StartBeforeIndent;
|
||||
var result = TryContinue(processor, null);
|
||||
if (result == BlockState.Continue)
|
||||
{
|
||||
// Save the column where we need to go back
|
||||
var column = processor.Column;
|
||||
|
||||
// Unwind all indents all spaces before in order to calculate correct span
|
||||
processor.UnwindAllIndents();
|
||||
|
||||
processor.NewBlocks.Push(new CodeBlock(this)
|
||||
{
|
||||
Column = startColumn,
|
||||
Span = new SourceSpan(startPosition, processor.Line.End)
|
||||
Column = processor.Column,
|
||||
Span = new SourceSpan(processor.Start, processor.Line.End)
|
||||
});
|
||||
|
||||
// Go back to the correct column
|
||||
processor.GoToColumn(column);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ namespace Markdig
|
||||
{
|
||||
public static partial class Markdown
|
||||
{
|
||||
public const string Version = "0.8.2";
|
||||
public const string Version = "0.8.4";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"title": "Markdig",
|
||||
"version": "0.8.2",
|
||||
"version": "0.8.4",
|
||||
"authors": [ "Alexandre Mutel" ],
|
||||
"description": "A fast, powerfull, CommonMark compliant, extensible Markdown processor for .NET with 20+ builtin extensions (pipetables, footnotes, definition lists... etc.)",
|
||||
"copyright": "Alexandre Mutel",
|
||||
@@ -11,7 +11,7 @@
|
||||
"projectUrl": "https://github.com/lunet-io/markdig",
|
||||
"iconUrl": "https://raw.githubusercontent.com/lunet-io/markdig/master/img/markdig.png",
|
||||
"requireLicenseAcceptance": false,
|
||||
"releaseNotes": "> 0.8.2\n- fix potential cast exception with Abreviation extension and empty literals\n> 0.8.1\n- new extension to disable URI escaping for non-US-ASCII characters to workaround a bug in Edge/IE\n- Fix an issue with abbreviations with left/right multiple non-punctuation/space characters\n> 0.8.0\n- Update to latest CommonMark specs\n- Fix empty literal\n- Add YAML frontmatter extension\n",
|
||||
"releaseNotes": "> 0.8.4\n- Fix issue when calculating the span of an indented code block within a list. Make sure to include first whitespace on the line\n> 0.8.3\n- fix NullReferenceException with Gridtables extension when a single `+` is entered on a line\n> 0.8.2\n- fix potential cast exception with Abreviation extension and empty literals\n> 0.8.1\n- new extension to disable URI escaping for non-US-ASCII characters to workaround a bug in Edge/IE\n- Fix an issue with abbreviations with left/right multiple non-punctuation/space characters\n> 0.8.0\n- Update to latest CommonMark specs\n- Fix empty literal\n- Add YAML frontmatter extension\n",
|
||||
"tags": [ "Markdown CommonMark md html md2html" ]
|
||||
},
|
||||
"configurations": {
|
||||
|
||||
Reference in New Issue
Block a user