예제 #1
0
        internal override BlockElement Close()
        {
            ListBlock ret = (ListBlock)base.Close();

            IsLastBlank = (ret.children.LastOrDefault() as ListItem)?.IsLastBlank == true;
            IsTight     = ret.Children.Cast <ListItem>().All(i => i.IsTight) &&
                          ret.Children.Reverse().Skip(1).Cast <ListItem>().All(c => !c.IsLastBlank);
            return(ret);
        }
예제 #2
0
        /// <summary>
        /// Gets the type of this block.
        /// </summary>
        internal override AddLineResult AddLine(string line, bool lazy, int currentIndent)
        {
            var trimmed = line.TrimStartAscii();

            if (content.Count == 0)
            {
                if (line.GetIndentNum(currentIndent) >= 4 || line.GetIndentNum(currentIndent) < 0)
                {
                    throw new InvalidBlockFormatException(BlockElementType.Unknown);
                }

                mayBeLinkReferenceDefinition = trimmed.StartsWith("[", StringComparison.Ordinal);
            }
            else if (line.GetIndentNum(currentIndent) < 4)
            {
                if (ListBlock.CanInterruptParagraph(line, currentIndent))
                {
                    actualType = BlockElementType.Paragraph;
                    return(AddLineResult.NeedClose);
                }

                string removed = line.Trim(whiteSpaceChars);
                if (removed.Length > 0 &&
                    !lazy &&
                    (removed[0] == '-' || removed[0] == '=') &&
                    removed.All(c => removed[0] == c) &&
                    !mayBeLinkReferenceDefinition)
                {
                    actualType  = BlockElementType.Heading;
                    headerLevel = removed[0] == '=' ? 1 : 2;
                    return(AddLineResult.Consumed | AddLineResult.NeedClose);
                }
            }

            if (Interrupted(line, currentIndent))
            {
                var match = linkDefinitionRegex.Match(string.Join("\n", content));
                actualType = match.Success && !IsBlank(match.Groups["label"].Value)
                    ? BlockElementType.LinkReferenceDefinition
                    : BlockElementType.Paragraph;
                return(AddLineResult.NeedClose);
            }

            if (mayBeLinkReferenceDefinition)
            {
                string removed = line.Trim(whiteSpaceChars);
                if (removed.Length > 0 &&
                    !lazy &&
                    (removed[0] == '-' || removed[0] == '=') &&
                    removed.All(c => removed[0] == c))
                {
                    actualType = BlockElementType.LinkReferenceDefinition;
                    return(AddLineResult.NeedClose);
                }
            }

            content.Add(trimmed);

            if (mayBeLinkReferenceDefinition)
            {
                string joined = string.Join("\n", content);
                var    match0 = linkDefinitionRegex.Match(joined);
                if (match0.Success && !IsBlank(match0.Groups["label"].Value))
                {
                    Match match = linkDefinitionRegex.Match(joined);
                    if (AreParenthesesBalanced(match.Groups["destination"].Value))
                    {
                        if (match.Groups["title"].Success)
                        {
                            actualType = BlockElementType.LinkReferenceDefinition;
                            return(AddLineResult.Consumed | AddLineResult.NeedClose);
                        }

                        if (linkDefinitionRegex.IsMatch(string.Join("\n", content.GetRange(0, content.Count - 1))))
                        {
                            content.RemoveAt(content.Count - 1);
                            actualType = BlockElementType.LinkReferenceDefinition;
                            return(AddLineResult.NeedClose);
                        }
                    }
                    else
                    {
                        mayBeLinkReferenceDefinition = false;
                    }
                }
                else
                {
                    var match1 = linkDefinitionRegex.Match(string.Join("\n", content.GetRange(0, content.Count - 1)));
                    if (match1.Success && !IsBlank(match1.Groups["label"].Value))
                    {
                        content.RemoveAt(content.Count - 1);
                        actualType = BlockElementType.LinkReferenceDefinition;
                        return(AddLineResult.NeedClose);
                    }
                }
            }

            return(AddLineResult.Consumed);
        }