public TagNode(BbTag tag, IEnumerable <SyntaxTreeNode> subNodes) : base(subNodes) { if (tag == null) { throw new ArgumentNullException(nameof(tag)); } Tag = tag; AttributeValues = new Dictionary <BbAttribute, string>(); }
private BbTag NoResult() { var toReturn = new BbTag { Start = lastStart - 1, End = currentPosition, Type = BbCodeType.None }; Last = toReturn; return(toReturn); }
private BbTag ReturnAsTextBetween(int start, int end) { if (end - start <= 1) { end = start + 2; } var toReturn = new BbTag { Type = BbCodeType.None, Start = start, End = end - 1 }; var rewindTo = Last?.End ?? 0; currentPosition = rewindTo; Last = toReturn; return(toReturn); }
internal static ParsedChunk FromTag(BbTag tag, string context) { var last = tag.ClosingTag?.End ?? tag.End; var toReturn = new ParsedChunk { Start = tag.Start, End = last, Type = tag.Type, Arguments = tag.Arguments }; if (tag.Children != null && tag.Children.Any()) { toReturn.Children = tag.Children.Select(x => FromTag(x, context)).ToList(); } if (tag.Type == BbCodeType.None) { toReturn.InnerText = context.Substring(tag.Start, tag.End - tag.Start); } return(toReturn); }
public BbTag Next() { if (HasReachedEnd) { return(NoResult()); } var openBrace = input.IndexOf('[', currentPosition); var closeBrace = input.IndexOf(']', currentPosition); currentPosition = closeBrace + 1; lastStart = openBrace + 1; if (openBrace == NotFound || closeBrace == NotFound) { HasReachedEnd = true; var start = Last?.End ?? 0; var end = input.Length; if (end - start > 0) { return(new BbTag { Type = BbCodeType.None, Start = start, End = end }); } return(null); } if (Last == null && openBrace > 0) { return(ReturnAsTextBetween(0, lastStart)); } if (Last != null && lastStart - Last.End > 1) { return(ReturnAsTextBetween(Last.End, lastStart)); } if (closeBrace < openBrace) { return(ReturnAsTextBetween(closeBrace, openBrace)); } arguments = null; var type = input.Substring(openBrace + 1, closeBrace - openBrace - 1); var equalsSign = type.IndexOf('='); if (equalsSign != NotFound) { var typeBeforeEquals = type.Substring(0, equalsSign); arguments = type.Substring(equalsSign + 1, type.Length - equalsSign - 1).Trim(); type = typeBeforeEquals.Trim(); } var isEndType = false; if (type.Length > 1) { isEndType = type[0].Equals('/'); type = isEndType ? type.Substring(1) : type; } var possibleMatch = Types.Keys.FirstOrDefault(x => x.Equals(type, StringComparison.Ordinal)); if (possibleMatch == null) { return(NoResult()); } Last = new BbTag { Arguments = arguments, End = currentPosition, Start = openBrace, Type = Types[possibleMatch], IsClosing = isEndType }; return(Last); }
public TagNode(BbTag tag) : this(tag, null) { }
private BbTag ReturnAsTextBetween(int start, int end) { if (end - start <= 1) end = start + 2; var toReturn = new BbTag { Type = BbCodeType.None, Start = start, End = end - 1 }; var rewindTo = Last != null ? Last.End : 0; currentPosition = rewindTo; Last = toReturn; return toReturn; }
private BbTag NoResult() { var toReturn = new BbTag { Start = lastStart - 1, End = currentPosition, Type = BbCodeType.None }; Last = toReturn; return toReturn; }
public BbTag Next() { if (HasReachedEnd) return NoResult(); var openBrace = input.IndexOf('[', currentPosition); var closeBrace = input.IndexOf(']', currentPosition); currentPosition = closeBrace + 1; lastStart = openBrace + 1; if (openBrace == NotFound || closeBrace == NotFound) { HasReachedEnd = true; var start = Last != null ? Last.End : 0; var end = input.Length; if (end - start > 0) { return new BbTag { Type = BbCodeType.None, Start = start, End = end }; } return null; } if (Last == null && openBrace > 0) return ReturnAsTextBetween(0, lastStart); if (Last != null && lastStart - Last.End > 1) return ReturnAsTextBetween(Last.End, lastStart); if (closeBrace < openBrace) return ReturnAsTextBetween(closeBrace, openBrace); arguments = null; var type = input.Substring(openBrace + 1, closeBrace - openBrace - 1); var equalsSign = type.IndexOf('='); if (equalsSign != NotFound) { var typeBeforeEquals = type.Substring(0, equalsSign); arguments = type.Substring(equalsSign + 1, type.Length - equalsSign - 1).Trim(); type = typeBeforeEquals.Trim(); } var isEndType = false; if (type.Length > 1) { isEndType = type[0].Equals('/'); type = isEndType ? type.Substring(1) : type; } var possibleMatch = Types.Keys.FirstOrDefault(x => x.Equals(type, StringComparison.Ordinal)); if (possibleMatch == null) return NoResult(); Last = new BbTag { Arguments = arguments, End = currentPosition, Start = openBrace, Type = Types[possibleMatch], IsClosing = isEndType }; return Last; }
internal static ParsedChunk FromTag(BbTag tag, string context) { var last = tag.ClosingTag != null ? tag.ClosingTag.End : tag.End; var toReturn = new ParsedChunk { Start = tag.Start, End = last, Type = tag.Type, Arguments = tag.Arguments }; if (tag.Children != null && tag.Children.Any()) toReturn.Children = tag.Children.Select(x => FromTag(x, context)).ToList(); if (tag.Type == BbCodeType.None) toReturn.InnerText = context.Substring(tag.Start, tag.End - tag.Start); return toReturn; }