T5.TextTemplating by Atif Aziz,Mikayla Hutchinson

<PackageReference Include="T5.TextTemplating" Version="1.1.0" />

 ParsedTemplate

public class ParsedTemplate
using Microsoft.VisualStudio.TextTemplating; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.IO; namespace T5.TextTemplating { public class ParsedTemplate { private readonly List<ISegment> segments = new List<ISegment>(); private readonly List<ISegment> importedHelperSegments = new List<ISegment>(); private readonly CompilerErrorCollection errors = new CompilerErrorCollection(); private readonly string rootFileName; public List<ISegment> RawSegments => segments; public IEnumerable<Directive> Directives { get { List<ISegment>.Enumerator enumerator = segments.GetEnumerator(); try { while (enumerator.MoveNext()) { Directive directive = enumerator.Current as Directive; if (directive != null) yield return directive; } } finally { ((IDisposable)enumerator).Dispose(); } enumerator = default(List<ISegment>.Enumerator); } } public IEnumerable<TemplateSegment> Content { get { List<ISegment>.Enumerator enumerator = segments.GetEnumerator(); try { while (enumerator.MoveNext()) { TemplateSegment templateSegment = enumerator.Current as TemplateSegment; if (templateSegment != null) yield return templateSegment; } } finally { ((IDisposable)enumerator).Dispose(); } enumerator = default(List<ISegment>.Enumerator); } } public CompilerErrorCollection Errors => errors; public ParsedTemplate(string rootFileName) { this.rootFileName = rootFileName; } public static ParsedTemplate FromText(string content, ITextTemplatingEngineHost host) { ParsedTemplate parsedTemplate = new ParsedTemplate(host.TemplateFile); try { parsedTemplate.Parse(host, new Tokeniser(host.TemplateFile, content)); return parsedTemplate; } catch (ParserException ex) { parsedTemplate.LogError(ex.Message, ex.Location); return parsedTemplate; } } public void Parse(ITextTemplatingEngineHost host, Tokeniser tokeniser) { Parse(host, tokeniser, true); } public void ParseWithoutIncludes(Tokeniser tokeniser) { Parse(null, tokeniser, false); } private void Parse(ITextTemplatingEngineHost host, Tokeniser tokeniser, bool parseIncludes) { Parse(host, tokeniser, parseIncludes, false); } private void Parse(ITextTemplatingEngineHost host, Tokeniser tokeniser, bool parseIncludes, bool isImport) { bool flag = false; bool flag2 = false; while ((flag || tokeniser.Advance()) && tokeniser.State != State.EOF) { flag = false; ISegment segment = null; switch (tokeniser.State) { case State.Block: if (!string.IsNullOrEmpty(tokeniser.Value)) segment = new TemplateSegment(SegmentType.Block, tokeniser.Value, tokeniser.Location); break; case State.Content: if (!string.IsNullOrEmpty(tokeniser.Value)) segment = new TemplateSegment(SegmentType.Content, tokeniser.Value, tokeniser.Location); break; case State.Expression: if (!string.IsNullOrEmpty(tokeniser.Value)) segment = new TemplateSegment(SegmentType.Expression, tokeniser.Value, tokeniser.Location); break; case State.Helper: flag2 = isImport; if (!string.IsNullOrEmpty(tokeniser.Value)) segment = new TemplateSegment(SegmentType.Helper, tokeniser.Value, tokeniser.Location); break; case State.Directive: { Directive directive = null; string text = null; while (!flag && tokeniser.Advance()) { switch (tokeniser.State) { case State.DirectiveName: if (directive == null) { directive = new Directive(tokeniser.Value, tokeniser.Location); directive.TagStartLocation = tokeniser.TagStartLocation; if (!parseIncludes || !string.Equals(directive.Name, "include", StringComparison.OrdinalIgnoreCase)) segments.Add(directive); } else text = tokeniser.Value; break; case State.DirectiveValue: if (text != null && directive != null) directive.Attributes[text] = tokeniser.Value; else LogError("Directive value without name", tokeniser.Location); text = null; break; case State.Directive: if (directive != null) directive.EndLocation = tokeniser.TagEndLocation; break; default: flag = true; break; } } if (parseIncludes && directive != null && string.Equals(directive.Name, "include", StringComparison.OrdinalIgnoreCase)) Import(host, directive, Path.GetDirectoryName(tokeniser.Location.FileName)); break; } default: throw new InvalidOperationException(); } if (segment != null) { segment.TagStartLocation = tokeniser.TagStartLocation; segment.EndLocation = tokeniser.TagEndLocation; if (flag2) importedHelperSegments.Add(segment); else segments.Add(segment); } } if (!isImport) AppendAnyImportedHelperSegments(); } private void Import(ITextTemplatingEngineHost host, Directive includeDirective, string relativeToDirectory) { if (includeDirective.Attributes.Count > 1 || !includeDirective.Attributes.TryGetValue("file", out string value)) LogError("Unexpected attributes in include directive", includeDirective.StartLocation); else { if (relativeToDirectory != null && !Path.IsPathRooted(value)) { string path = Path.Combine(relativeToDirectory, value); if (File.Exists(path)) value = Path.GetFullPath(path); } if (host.LoadIncludeText(value, out string content, out string location)) Parse(host, new Tokeniser(location, content), true, true); else LogError("Could not resolve include file '" + value + "'.", includeDirective.StartLocation); } } private void AppendAnyImportedHelperSegments() { segments.AddRange(importedHelperSegments); importedHelperSegments.Clear(); } private void LogError(string message, Location location, bool isWarning) { CompilerError compilerError = new CompilerError(); compilerError.ErrorText = message; if (location.FileName != null) { compilerError.Line = location.Line; compilerError.Column = location.Column; compilerError.FileName = (location.FileName ?? string.Empty); } else compilerError.FileName = (rootFileName ?? string.Empty); compilerError.IsWarning = isWarning; errors.Add(compilerError); } public void LogError(string message) { LogError(message, Location.Empty, false); } public void LogWarning(string message) { LogError(message, Location.Empty, true); } public void LogError(string message, Location location) { LogError(message, location, false); } public void LogWarning(string message, Location location) { LogError(message, location, true); } } }