diff --git a/src/Textamina.Markdig.Tests/Specs/PipeTableSpecs.md b/src/Textamina.Markdig.Tests/Specs/PipeTableSpecs.md
index f07c50dd..91765afa 100644
--- a/src/Textamina.Markdig.Tests/Specs/PipeTableSpecs.md
+++ b/src/Textamina.Markdig.Tests/Specs/PipeTableSpecs.md
@@ -377,3 +377,29 @@ a | b
````````````````````````````````
+
+**Rule #8**
+
+The character `|` inside a link label is not recognize as a column delimiter
+
+```````````````````````````````` example
+a | b
+-- | --
+[This is a link with a | inside the label](http://google.com) | 1
+.
+
+````````````````````````````````
+
diff --git a/src/Textamina.Markdig.Tests/Specs/Specs.cs b/src/Textamina.Markdig.Tests/Specs/Specs.cs
index 719475b5..79d3986b 100644
--- a/src/Textamina.Markdig.Tests/Specs/Specs.cs
+++ b/src/Textamina.Markdig.Tests/Specs/Specs.cs
@@ -16776,6 +16776,43 @@ namespace Textamina.Markdig.Tests
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 16, "Extensions Pipe Table");
TestParser.TestSpec("a | b\n-- | --\n0 | 1", "\n\n\n| a | \nb | \n
\n\n\n\n| 0 | \n1 | \n
\n\n
", "pipetables");
}
+ }
+ // **Rule #8**
+ //
+ // Links labels are escaping `|`
+ [TestFixture]
+ public partial class TestExtensionsPipeTable
+ {
+ [Test]
+ public void Example017()
+ {
+ // Example 17
+ // Section: Extensions Pipe Table
+ //
+ // The following CommonMark:
+ // a | b
+ // -- | --
+ // [This is a link with a | inside the label](http://google.com) | 1
+ //
+ // Should be rendered as:
+ //
+
+ Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 17, "Extensions Pipe Table");
+ TestParser.TestSpec("a | b\n-- | --\n[This is a link with a | inside the label](http://google.com) | 1", "", "pipetables");
+ }
}
// # Extensions
//
diff --git a/src/Textamina.Markdig/Extensions/Tables/PipeTableInlineParser.cs b/src/Textamina.Markdig/Extensions/Tables/PipeTableInlineParser.cs
index a9ff5552..e9fa02da 100644
--- a/src/Textamina.Markdig/Extensions/Tables/PipeTableInlineParser.cs
+++ b/src/Textamina.Markdig/Extensions/Tables/PipeTableInlineParser.cs
@@ -109,11 +109,81 @@ namespace Textamina.Markdig.Extensions.Tables
return true;
}
- public bool ProcessDelimiters(InlineParserState state, Inline root, Inline lastChild, int delimiterProcessorIndex)
+ public bool ProcessDelimiters(InlineParserState state, Inline root, Inline lastChild, int delimiterProcessorIndex, bool isFinalProcessing)
{
- // Continue
var container = root as ContainerInline;
var tableState = state.ParserStates[Index] as TableState;
+
+ // If the delimiters are being processed by an image link, we need to transform them back to literals
+ if (!isFinalProcessing)
+ {
+ if (container == null || tableState == null)
+ {
+ return true;
+ }
+
+ var child = container.LastChild;
+ List delimitersToRemove = null;
+
+ while (child != null)
+ {
+ var pipeDelimiter = child as PiprTableDelimiterInline;
+ if (pipeDelimiter != null)
+ {
+ if (delimitersToRemove == null)
+ {
+ delimitersToRemove = new List();
+ }
+ delimitersToRemove.Add(pipeDelimiter);
+ }
+
+ if (child == lastChild)
+ {
+ break;
+ }
+
+ var subContainer = child as ContainerInline;
+ child = subContainer?.LastChild;
+ }
+
+ // If we have found any delimiters, transform them to literals
+ if (delimitersToRemove != null)
+ {
+ bool leftIsDelimiter = false;
+ bool rightIsDelimiter = false;
+ for (int i = 0; i < delimitersToRemove.Count; i++)
+ {
+ var pipeDelimiter = delimitersToRemove[i];
+ pipeDelimiter.ReplaceBy(new LiteralInline() {Content = new StringSlice("|"), IsClosed = true});
+
+ // Check that the pipe that is being removed is not going to make a line without pipe delimiters
+ var tableDelimiters = tableState.ColumnAndLineDelimiters;
+ var delimiterIndex = tableDelimiters.IndexOf(pipeDelimiter);
+
+ if (i == 0)
+ {
+ leftIsDelimiter = delimiterIndex > 0 && tableDelimiters[delimiterIndex - 1] is PiprTableDelimiterInline;
+ }
+ else if (i + 1 == delimitersToRemove.Count)
+ {
+ rightIsDelimiter = delimiterIndex + 1 < tableDelimiters.Count &&
+ tableDelimiters[delimiterIndex + 1] is PiprTableDelimiterInline;
+ }
+ // Remove this delimiter from the table state
+ tableState.ColumnAndLineDelimiters.Remove(pipeDelimiter);
+ }
+
+ // If we didn't have any delimiter before and after the delimiters we jsut removed, we mark the state of the current line as no pipe
+ if (!leftIsDelimiter && !rightIsDelimiter)
+ {
+ tableState.LineHasPipe = false;
+ }
+ }
+
+ return true;
+ }
+
+ // Continue
if (tableState == null || container == null || tableState.IsInvalidTable || !tableState.LineHasPipe || tableState.LineIndex != state.LocalLineIndex)
{
return true;
@@ -258,7 +328,7 @@ namespace Textamina.Markdig.Extensions.Tables
{
foreach (var cell in cells)
{
- state.ProcessDelimiters(i + 1, cell.Inline);
+ state.ProcessDelimiters(i + 1, cell.Inline, null, true);
}
break;
}
diff --git a/src/Textamina.Markdig/Parsers/IDelimiterProcessor.cs b/src/Textamina.Markdig/Parsers/IDelimiterProcessor.cs
index 0e31661c..6878bc8d 100644
--- a/src/Textamina.Markdig/Parsers/IDelimiterProcessor.cs
+++ b/src/Textamina.Markdig/Parsers/IDelimiterProcessor.cs
@@ -17,8 +17,9 @@ namespace Textamina.Markdig.Parsers
/// The root inline.
/// The last child.
/// Index of this delimiter processor.
+ ///
/// true to continue to the next delimiter processor;
/// false to stop the process (in case a processor is perfoming sub-sequent processor itself)
- bool ProcessDelimiters(InlineParserState state, Inline root, Inline lastChild, int delimiterProcessorIndex);
+ bool ProcessDelimiters(InlineParserState state, Inline root, Inline lastChild, int delimiterProcessorIndex, bool isFinalProcessing);
}
}
\ No newline at end of file
diff --git a/src/Textamina.Markdig/Parsers/InlineParserState.cs b/src/Textamina.Markdig/Parsers/InlineParserState.cs
index 30216b70..83c7befe 100644
--- a/src/Textamina.Markdig/Parsers/InlineParserState.cs
+++ b/src/Textamina.Markdig/Parsers/InlineParserState.cs
@@ -218,7 +218,7 @@ namespace Textamina.Markdig.Parsers
}
// Process all delimiters
- ProcessDelimiters(0, Root);
+ ProcessDelimiters(0, Root, null, true);
//TransformDelimitersToLiterals();
@@ -230,12 +230,12 @@ namespace Textamina.Markdig.Parsers
}
}
- public void ProcessDelimiters(int startingIndex, Inline root, Inline lastChild = null)
+ public void ProcessDelimiters(int startingIndex, Inline root, Inline lastChild, bool isFinalProcessing)
{
for (int i = startingIndex; i < Parsers.DelimiterProcessors.Length; i++)
{
var delimiterProcessor = Parsers.DelimiterProcessors[i];
- if (!delimiterProcessor.ProcessDelimiters(this, root, lastChild, i))
+ if (!delimiterProcessor.ProcessDelimiters(this, root, lastChild, i, isFinalProcessing))
{
break;
}
diff --git a/src/Textamina.Markdig/Parsers/Inlines/EmphasisInlineParser.cs b/src/Textamina.Markdig/Parsers/Inlines/EmphasisInlineParser.cs
index 689ca855..09c44310 100644
--- a/src/Textamina.Markdig/Parsers/Inlines/EmphasisInlineParser.cs
+++ b/src/Textamina.Markdig/Parsers/Inlines/EmphasisInlineParser.cs
@@ -22,7 +22,7 @@ namespace Textamina.Markdig.Parsers.Inlines
OpeningCharacters = new[] { '*', '_' };
}
- public bool ProcessDelimiters(InlineParserState state, Inline root, Inline lastChild, int delimiterProcessorIndex)
+ public bool ProcessDelimiters(InlineParserState state, Inline root, Inline lastChild, int delimiterProcessorIndex, bool isFinalProcessing)
{
var container = root as ContainerInline;
if (container == null)
diff --git a/src/Textamina.Markdig/Parsers/Inlines/LinkInlineParser.cs b/src/Textamina.Markdig/Parsers/Inlines/LinkInlineParser.cs
index 1e10a606..48931803 100644
--- a/src/Textamina.Markdig/Parsers/Inlines/LinkInlineParser.cs
+++ b/src/Textamina.Markdig/Parsers/Inlines/LinkInlineParser.cs
@@ -13,8 +13,6 @@ namespace Textamina.Markdig.Parsers.Inlines
///
public class LinkInlineParser : InlineParser
{
- private int emphasisInlineDelimiterProcessorIndex;
-
///
/// Initializes a new instance of the class.
///
@@ -23,21 +21,6 @@ namespace Textamina.Markdig.Parsers.Inlines
OpeningCharacters = new[] {'[', ']', '!'};
}
- public override void Initialize(InlineParserState state)
- {
- // Look for emphasis delimiter processor
- emphasisInlineDelimiterProcessorIndex = -1;
- for (int i = 0; i < state.Parsers.DelimiterProcessors.Length; i++)
- {
- var delimiters = state.Parsers.DelimiterProcessors[i];
- if (delimiters is EmphasisInlineParser)
- {
- emphasisInlineDelimiterProcessorIndex = i;
- break;
- }
- }
- }
-
public override bool Match(InlineParserState state, ref StringSlice slice)
{
// The following methods are inspired by the "An algorithm for parsing nested emphasis and links"
@@ -151,10 +134,7 @@ namespace Textamina.Markdig.Parsers.Inlines
link.IsClosed = true;
// Process emphasis delimiters
- if (emphasisInlineDelimiterProcessorIndex >= 0)
- {
- state.ProcessDelimiters(emphasisInlineDelimiterProcessorIndex, link);
- }
+ state.ProcessDelimiters(0, link, null, false);
state.Inline = link;
isValidLink = true;
@@ -221,10 +201,7 @@ namespace Textamina.Markdig.Parsers.Inlines
inlineState.Inline = link;
// Process emphasis delimiters
- if (emphasisInlineDelimiterProcessorIndex >= 0)
- {
- inlineState.ProcessDelimiters(emphasisInlineDelimiterProcessorIndex, link);
- }
+ inlineState.ProcessDelimiters(0, link, null, false);
// If we have a link (and not an image),
// we also set all [ delimiters before the opening delimiter to inactive.