public static InlineStack FindMatchingOpener(InlineStack seachBackwardsFrom, InlineStackPriority priority, char delimeter, out bool canClose) { canClose = true; var istack = seachBackwardsFrom; while (true) { if (istack == null) { // this cannot be a closer since there is no opener available. canClose = false; return null; } if (istack.Priority > priority || (istack.Delimeter == delimeter && 0 != (istack.Flags & InlineStackFlags.Closer))) { // there might be a closer further back but we cannot go there yet because a higher priority element is blocking // the other option is that the stack entry could be a closer for the same char - this means // that any opener we might find would first have to be matched against this closer. return null; } if (istack.Delimeter == delimeter) return istack; istack = istack.Previous; } }
public static InlineStack FindMatchingOpener(InlineStack seachBackwardsFrom, InlineStackPriority priority, char delimiter, out bool canClose) { canClose = true; var istack = seachBackwardsFrom; while (true) { if (istack == null) { // this cannot be a closer since there is no opener available. canClose = false; return(null); } if (istack.Priority > priority || (istack.Delimiter == delimiter && 0 != (istack.Flags & InlineStackFlags.Closer))) { // there might be a closer further back but we cannot go there yet because a higher priority element is blocking // the other option is that the stack entry could be a closer for the same char - this means // that any opener we might find would first have to be matched against this closer. return(null); } if (istack.Delimiter == delimiter) { return(istack); } istack = istack.Previous; } }
public static InlineStack FindMatchingOpener(InlineStack searchBackwardsFrom, InlineStackPriority priority, char delimiter, int closerDelimiterCount, bool closerCanOpen, out bool canClose) { canClose = true; var istack = searchBackwardsFrom; while (true) { if (istack == null) { // this cannot be a closer since there is no opener available. canClose = false; return null; } if (istack.Priority > priority || (istack.Delimiter == delimiter && 0 != (istack.Flags & InlineStackFlags.Closer))) { // there might be a closer further back but we cannot go there yet because a higher priority element is blocking // the other option is that the stack entry could be a closer for the same char - this means // that any opener we might find would first have to be matched against this closer. return null; } if (istack.Delimiter == delimiter) { // interior closer of size 2 does not match opener of size 1 and vice versa. // for more details, see https://github.com/jgm/cmark/commit/c50197bab81d7105c9c790548821b61bcb97a62a var oddMatch = (closerCanOpen || (istack.Flags & InlineStackFlags.CloserOriginally) > 0) && istack.DelimiterCount != closerDelimiterCount && ((istack.DelimiterCount + closerDelimiterCount) % 3 == 0); if (!oddMatch) return istack; } istack = istack.Previous; } }
public static InlineStack FindMatchingOpener(InlineStack searchBackwardsFrom, InlineStackPriority priority, char delimiter, int closerDelimiterCount, bool closerCanOpen, out bool canClose) { canClose = true; var istack = searchBackwardsFrom; while (true) { if (istack == null) { // this cannot be a closer since there is no opener available. canClose = false; return(null); } if (istack.Priority > priority || (istack.Delimiter == delimiter && 0 != (istack.Flags & InlineStackFlags.Closer))) { // there might be a closer further back but we cannot go there yet because a higher priority element is blocking // the other option is that the stack entry could be a closer for the same char - this means // that any opener we might find would first have to be matched against this closer. return(null); } if (istack.Delimiter == delimiter) { // interior closer of size 2 does not match opener of size 1 and vice versa. // for more details, see https://github.com/jgm/cmark/commit/c50197bab81d7105c9c790548821b61bcb97a62a var oddMatch = (closerCanOpen || (istack.Flags & InlineStackFlags.CloserOriginally) > 0) && istack.DelimiterCount != closerDelimiterCount && ((istack.DelimiterCount + closerDelimiterCount) % 3 == 0); if (!oddMatch) { return(istack); } } istack = istack.Previous; } }
public static void PostProcessInlineStack(Subject subj, InlineStack first, InlineStack last, InlineStackPriority ignorePriority) { while (ignorePriority > 0) { var istack = first; while (istack != null) { if (istack.Priority >= ignorePriority) { RemoveStackEntry(istack, subj, istack); } else if (0 != (istack.Flags & InlineStackFlags.Closer)) { bool canClose; var iopener = FindMatchingOpener(istack.Previous, istack.Priority, istack.Delimiter, istack.DelimiterCount, (istack.Flags & InlineStackFlags.Opener) > 0, out canClose); if (iopener != null) { bool retry = false; if (iopener.Delimiter == '~') { InlineMethods.MatchInlineStack(iopener, subj, istack.DelimiterCount, istack, (InlineTag)0, InlineTag.Strikethrough); if (istack.DelimiterCount > 1) { retry = true; } } else { var useDelims = InlineMethods.MatchInlineStack(iopener, subj, istack.DelimiterCount, istack, InlineTag.Emphasis, InlineTag.Strong); if (istack.DelimiterCount > 0) { retry = true; } } if (retry) { // remove everything between opened and closer (not inclusive). if (istack.Previous != null && iopener.Next != istack.Previous) { RemoveStackEntry(iopener.Next, subj, istack.Previous); } continue; } else { // remove opener, everything in between, and the closer RemoveStackEntry(iopener, subj, istack); } } else if (!canClose) { // this case means that a matching opener does not exist // remove the Closer flag so that a future Opener can be matched against it. istack.Flags &= ~InlineStackFlags.Closer; } } if (istack == last) { break; } istack = istack.Next; } ignorePriority--; } }
public static void PostProcessInlineStack(Subject subj, InlineStack first, InlineStack last, InlineStackPriority ignorePriority, InlineParserParameters parameters) { var singleCharTags = parameters.SingleCharTags; var doubleCharTags = parameters.DoubleCharTags; while (ignorePriority > 0) { var istack = first; while (istack != null) { if (istack.Priority >= ignorePriority) { RemoveStackEntry(istack, subj, istack, parameters); } else if (0 != (istack.Flags & InlineStackFlags.Closer)) { bool canClose; var iopener = FindMatchingOpener(istack.Previous, istack.Priority, istack.Delimeter, out canClose); if (iopener != null) { bool retry = false; var singleCharTag = iopener.Delimeter < singleCharTags.Length ? singleCharTags[iopener.Delimeter] : (InlineTag)0; var doubleCharTag = iopener.Delimeter < doubleCharTags.Length ? doubleCharTags[iopener.Delimeter] : (InlineTag)0; if (singleCharTag != 0 || doubleCharTag != 0) { var useDelims = InlineMethods.MatchInlineStack(iopener, subj, istack.DelimeterCount, istack, singleCharTag, doubleCharTag, parameters); if (istack.DelimeterCount > 0) retry = true; } if (retry) { // remove everything between opened and closer (not inclusive). if (istack.Previous != null && iopener.Next != istack.Previous) RemoveStackEntry(iopener.Next, subj, istack.Previous, parameters); continue; } else { // remove opener, everything in between, and the closer RemoveStackEntry(iopener, subj, istack, parameters); } } else if (!canClose) { // this case means that a matching opener does not exist // remove the Closer flag so that a future Opener can be matched against it. istack.Flags &= ~InlineStackFlags.Closer; } } if (istack == last) break; istack = istack.Next; } ignorePriority--; } }
public static void PostProcessInlineStack(Subject subj, InlineStack first, InlineStack last, InlineStackPriority ignorePriority) { while (ignorePriority > 0) { var istack = first; while (istack != null) { if (istack.Priority >= ignorePriority) { RemoveStackEntry(istack, subj, istack); } else if (0 != (istack.Flags & InlineStackFlags.Closer)) { bool canClose; var iopener = FindMatchingOpener(istack.Previous, istack.Priority, istack.Delimeter, out canClose); if (iopener != null) { bool retry = false; if (iopener.Delimeter == '~') { InlineMethods.MatchInlineStack(iopener, subj, istack.DelimeterCount, istack, null, InlineTag.Strikethrough); if (istack.DelimeterCount > 1) retry = true; } else { var useDelims = InlineMethods.MatchInlineStack(iopener, subj, istack.DelimeterCount, istack, InlineTag.Emphasis, InlineTag.Strong); if (istack.DelimeterCount > 0) retry = true; } if (retry) { // remove everything between opened and closer (not inclusive). if (istack.Previous != null && iopener.Next != istack.Previous) RemoveStackEntry(iopener.Next, subj, istack.Previous); continue; } else { // remove opener, everything in between, and the closer RemoveStackEntry(iopener, subj, istack); } } else if (!canClose) { // this case means that a matching opener does not exist // remove the Closer flag so that a future Opener can be matched against it. istack.Flags &= ~InlineStackFlags.Closer; } } if (istack == last) break; istack = istack.Next; } ignorePriority--; } }