/// <summary> /// Adds a line of string to this block. /// </summary> /// <param name="line">A single line to add to this element.</param> /// <param name="lazy">Whether <paramref name="line"/> is lazy continuation.</param> /// <param name="currentIndent">The indent count of <paramref name="line"/>.</param> /// <returns></returns> internal override AddLineResult AddLine(string line, bool lazy, int currentIndent) { if (HasMark(line, currentIndent, out string markRemoved, out int markLength)) { AddLineResult addLineResult; do { if (openElement == null) { openElement = BlockElementUtil.CreateBlockFromLine(markRemoved, currentIndent, parserConfig, Type == BlockElementType.List); children.Add(openElement); } addLineResult = openElement.AddLine(markRemoved, lazy, currentIndent + markLength); if ((addLineResult & AddLineResult.NeedClose) != 0) { children[children.Count - 1] = openElement.Close(); openElement = null; } } while ((addLineResult & AddLineResult.Consumed) == 0); return(addLineResult & AddLineResult.Consumed); } line = markRemoved ?? line; var newElem = BlockElementUtil.CreateBlockFromLine(line, currentIndent, parserConfig, Type == BlockElementType.List); if ((newElem.Type != BlockElementType.Unknown && newElem.Type != BlockElementType.BlankLine && newElem.Type != BlockElementType.CodeBlock) || !CanLazyContinue()) { return(AddLineResult.NeedClose); } return(openElement?.AddLine(line, true, currentIndent) ?? throw new Exception()); }
/// <summary> /// Adds a line of string to this <see cref="AtxHeading"/>. /// </summary> /// <param name="line">A single line to add to this element.</param> /// <param name="lazy">Whether <paramref name="line"/> is lazy continuation.</param> /// <param name="currentIndent">The indent count of <paramref name="line"/>.</param> /// <returns> /// Returns <c>AddLineResult.Consumed | AddLineResult.NeedClose</c> /// except when this block need to be interrupted. /// </returns> internal override AddLineResult AddLine(string line, bool lazy, int currentIndent) { int lineIndent = line.GetIndentNum(currentIndent); string lineTrimmed = line.TrimStartAscii(); int trimmedIndent = lineIndent + currentIndent; if (openElement == null) { if (lineIndent < 0 || lineIndent >= 4) { throw new InvalidBlockFormatException(BlockElementType.List); } var item = CreateItem(lineTrimmed, trimmedIndent); AddChild(item); item.contentIndent += lineIndent; item.MarkIndent += lineIndent; openElement.AddLine( item.contentIndent > line.Length ? string.Empty : SubStringExpandingTabs(line, item.contentIndent, currentIndent), false, currentIndent + item.contentIndent); return(AddLineResult.Consumed); } if (!(openElement is ListItem listItem)) { throw new InvalidBlockFormatException(BlockElementType.List); } if (lineIndent == -1) { return(listItem.AddLine(line, true, currentIndent)); } if (lazy) { return(listItem.AddLine(line, true, currentIndent)); } if (lineIndent >= listItem.contentIndent) { return(listItem.AddLine(SubStringExpandingTabs(line, listItem.contentIndent, currentIndent), false, currentIndent + listItem.contentIndent)); } if (trimmedIndent < 4 && CanStartBlock(lineTrimmed, currentIndent)) { if (ThematicBreak.CanStartBlock(line, currentIndent)) { return(AddLineResult.NeedClose); } var newItem = CreateItem(lineTrimmed, trimmedIndent); if (newItem.Deliminator != listItem.Deliminator) { return(AddLineResult.NeedClose); } CloseOpenElement(); AddChild(newItem); newItem.contentIndent += lineIndent; newItem.MarkIndent += lineIndent; openElement.AddLine( SubStringExpandingTabs(line, Math.Min(newItem.contentIndent, line.Length), currentIndent), false, currentIndent + Math.Min(newItem.contentIndent, line.Length)); return(AddLineResult.Consumed); } if (!CanLazyContinue()) { return(AddLineResult.NeedClose); } var indentRemoved = RemoveIndent(line, listItem.contentIndent, currentIndent); var newBlock = BlockElementUtil.CreateBlockFromLine(indentRemoved, currentIndent + Math.Min(listItem.contentIndent, lineIndent), parserConfig); if (newBlock.Type == BlockElementType.ThematicBreak) { return(AddLineResult.NeedClose); } return(openElement.AddLine(line, true, currentIndent) & AddLineResult.Consumed); }