public static void Text(this TokenStream stream, string text, MarkdownTokens flag = MarkdownTokens.None) { if (MergeText(stream.Current, text, flag)) { return; } stream.Add(new MarkdownToken() { Type = MarkdownTokenType.Text, Text = text, Flag = flag }); }
private static bool MergeText(MarkdownToken current, string text, MarkdownTokens flag) { // Only allow merge if the previous token was text if (current == null || current.Type != MarkdownTokenType.Text) { return(false); } if (current.Flag.ShouldPreserve()) { return(false); } // If the previous token was text, lessen the break but still don't allow merging if (current.Flag.HasFlag(MarkdownTokens.LineBreak) && !current.Flag.ShouldPreserve()) { return(false); } // Text must have the same flags set if (current.Flag.HasFlag(MarkdownTokens.Italic) != flag.HasFlag(MarkdownTokens.Italic)) { return(false); } if (current.Flag.HasFlag(MarkdownTokens.Bold) != flag.HasFlag(MarkdownTokens.Bold)) { return(false); } if (current.Flag.HasFlag(MarkdownTokens.Code) != flag.HasFlag(MarkdownTokens.Code)) { return(false); } if (!current.Flag.IsEnding()) { current.Text = string.Concat(current.Text, text); } else if (current.Flag == MarkdownTokens.LineEnding) { return(false); } // Take on the ending of the merged token current.Flag = flag; return(true); }
public static bool ShouldPreserve(this MarkdownTokens flags) { return(flags.HasFlag(MarkdownTokens.Preserve)); }
public static bool IsLineBreak(this MarkdownTokens flags) { return(flags.HasFlag(MarkdownTokens.LineBreak)); }
public static bool IsEnding(this MarkdownTokens flags) { return(flags.HasFlag(MarkdownTokens.LineEnding) || flags.HasFlag(MarkdownTokens.LineBreak)); }
private string UnwrapStyleMarkers(MarkdownStream stream, out MarkdownTokens flag) { flag = MarkdownTokens.None; // Check for style var styleChar = stream.Current; var stylePrevious = stream.Previous; var styleCount = styleChar == Asterix || styleChar == Underscore?stream.Skip(styleChar, max : 0) : 0; var codeCount = styleChar == Backtick?stream.Skip(Backtick, max : 0) : 0; var text = stream.CaptureUntil(IsTextStop, ignoreEscaping: false); // Check for italic and bold endings if (styleCount > 0) { if (stream.Current == styleChar) { var styleEnding = stream.Skip(styleChar, max: styleCount); // Add back underscores within text if (styleChar == Underscore && stylePrevious != Whitespace) { return(Pad(text, styleChar, left: styleCount, right: styleCount)); } // Add back asterixes/underscores that are part of text if (styleEnding < styleCount) { text = Pad(text, styleChar, left: styleCount - styleEnding); } if (styleEnding == 1 || styleEnding == 3) { flag |= MarkdownTokens.Italic; } if (styleEnding >= 2) { flag |= MarkdownTokens.Bold; } } else { // Add back asterixes/underscores that are part of text text = Pad(text, styleChar, left: styleCount); } } if (codeCount > 0) { if (stream.Current == styleChar) { var codeEnding = stream.Skip(styleChar, max: 1); // Add back backticks that are part of text if (codeEnding < codeCount) { text = Pad(text, styleChar, left: codeCount - codeEnding); } if (codeEnding == 1) { flag |= MarkdownTokens.Code; } } else { // Add back backticks that are part of text text = Pad(text, styleChar, left: codeCount); } } return(text); }