/// <summary> /// Initializes a new instance of the <see cref="SpanBuilder"/> class. /// </summary> /// <param name="original">The original span.</param> public SpanBuilder(Span original) { Collapsed = original.Collapsed; Kind = original.Kind; _symbols = new List<ISymbol>(original.Symbols); Start = original.Start; }
/// <inheritdoc /> public override void Render(Span target, RenderContext context, TextWriter writer) { if (target.Collapsed) { // Span is collapsed, so do not render. return; } string content = target == null || target.Content == null ? string.Empty : target.Content; Write(context, writer, new SafeString(content)); }
public Block Block(BlockType type, string name = null, params SyntaxTreeNode[] children) { _last = null; var builder = new BlockBuilder(); builder.Type = type; builder.Name = name; foreach (var child in children) { builder.Children.Add(child); } return builder.Build(); }
public Span Span(SpanKind kind, params ISymbol[] symbols) { var builder = new SpanBuilder(); builder.Kind = kind; foreach (var symbol in symbols) { builder.Accept(symbol); } var span = builder.Build(); if (_last != null) { span.Previous = _last; _last.Next = span; } _last = span; return span; }
/// <summary> /// Collapses the previous whitespace instance. /// </summary> /// <param name="span">The tilde span.</param> private void CollapsePreviousWhiteSpace(Span span) { // Traverse to parent block. (TagElement | Expression) var element = span.Parent; Block scope = null; List<SyntaxTreeNode> children; if (element.Type == BlockType.TagElement || element.Type == BlockType.Expression || element.Type == BlockType.Comment || element.Type == BlockType.Partial) { scope = element.Parent; // Up to parent block containing the Expression tag. children = scope.Children.ToList(); if (children[0].Equals(element)) { CollapsePreviousWhiteSpace(scope.Parent, scope); } else { CollapsePreviousWhiteSpace(scope, element); } } }
/// <inheritdoc /> public override void Render(Span target, RenderContext context, TextWriter writer) { object value = context.ResolveValue(target); Write(context, writer, value); }
/// <summary> /// Resolves the value represented by the given span. /// </summary> /// <param name="span">The span representing the expression.</param> /// <returns>The resolved value.</returns> public object ResolveValue(Span span) { IEnumerable<ISymbol> symbols; switch (span.Kind) { case SpanKind.Expression: case SpanKind.Parameter: { symbols = span.Symbols; break; } case SpanKind.Map: { symbols = span.Symbols.Skip(2); break; } default: { return TemplateData.Model; } } return ResolveValueFromSymbols(symbols.ToArray()); }
/// <summary> /// Adds the span. /// </summary> /// <param name="span">The span.</param> public void AddSpan(Span span) { EnsureNotTerminated(); if (_blockStack.Count == 0) { throw new InvalidOperationException("No current block"); } span.Previous = LastSpan; if (LastSpan != null) { LastSpan.Next = span; } _blockStack.Peek().Children.Add(span); LastSpan = span; }
/// <summary> /// Visits a ~ character which allows collapsing of whitespace. /// </summary> /// <param name="span">The tilde span.</param> public void VisitTilde(Span span) { if (span.Previous != null && span.Previous.Kind == SpanKind.MetaCode && span.Previous.Content.EndsWith("{{")) { CollapsePreviousWhiteSpace(span); } else if (span.Next != null && span.Next.Kind == SpanKind.MetaCode && span.Next.Content.StartsWith("}}")) { CollapseNextWhiteSpace(span); } }
/// <inheritdoc /> public override void VisitSpan(Span span) { if (span.Kind == SpanKind.MetaCode) { var symbol = span.Symbols.FirstOrDefault() as HandlebarsSymbol; if (symbol != null && symbol.Type == HandlebarsSymbolType.Tilde) { VisitTilde(span); } } base.VisitSpan(span); }
/// <inheritdoc /> public virtual void VisitSpan(Span span) { }