Exemplo n.º 1
0
        /// <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());
        }
Exemplo n.º 2
0
        /// <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);
        }