/// <summary> /// Returns whether this element allow lazy continuation. /// </summary> /// <returns> /// Returns <c>true</c> when lazy continuation is allowed, <c>false</c> otherwise. /// </returns> protected bool CanLazyContinue() { if (children.Count == 0) { return(false); } BlockElementType lastElementType = children.Last().Type; if (children.Last() is ContainerElement container) { return(container.CanLazyContinue()); } return(lastElementType == BlockElementType.Unknown || lastElementType == BlockElementType.Paragraph); }
public InvalidBlockFormatException(BlockElementType elementType, string message) : this(elementType) { this.message = message; }
/// <summary> /// Initializes new instance of <see cref="InvalidBlockFormatException"/>. /// </summary> /// <param name="elementType"></param> public InvalidBlockFormatException(BlockElementType elementType) { ElementType = elementType; }
public BlockElementStructure(BlockElementType type, params BlockElementStructure[] structures) { Content = type; Children = structures ?? throw new ArgumentNullException(nameof(structures)); }
/// <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); }
internal UnknownElement(ParserConfig config) : base(config) { content = new List <string>(); actualType = BlockElementType.Unknown; }