diff --git a/BasicDemo/BasicDemo.csproj b/BasicDemo/BasicDemo.csproj new file mode 100644 index 0000000..a7f0773 --- /dev/null +++ b/BasicDemo/BasicDemo.csproj @@ -0,0 +1,20 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + + + Always + + + + diff --git a/BasicDemo/Program.cs b/BasicDemo/Program.cs new file mode 100644 index 0000000..f23151f --- /dev/null +++ b/BasicDemo/Program.cs @@ -0,0 +1,23 @@ +// See https://aka.ms/new-console-template for more information + +using mROA.CodegenTools; + +// var doc = new TemplateDocument(); +// doc.Parts = new List +// { +// new LiteralTemplateSection("teset text", doc), +// new DefineTemplateSection(" another text which is dinided, bun not placed ", "text define", doc), +// new LinkTemplateSection("text define", doc), +// new LinkTemplateSection("text define", doc), +// new LinkTemplateSection("text define", doc), +// new LiteralTemplateSection(" = = = ", doc), +// new InsertTemplatePart("insert", doc), +// new LinkTemplateSection("post", doc) +// }; +// +// doc.Insert("insert", "inserted text by insert template => "); +// doc.Parts.Add(new DefineTemplateSection("post added", "post", doc)); +// Console.WriteLine(doc.Compile()); + +var doc = TemplateReader.Parce(File.ReadAllText("exampleTemplate.cstmpl")); +Console.WriteLine(doc.Parts.Count); \ No newline at end of file diff --git a/BasicDemo/exampleTemplate.cstmpl b/BasicDemo/exampleTemplate.cstmpl new file mode 100644 index 0000000..5e47243 --- /dev/null +++ b/BasicDemo/exampleTemplate.cstmpl @@ -0,0 +1,19 @@ +public class A +{ + + + + Some literal for test + test text with definition in template + + + + + + + public void () + { + Console.WriteLine(""); + } + +} \ No newline at end of file diff --git a/mROA.CodegenTools/DefineTemplateSection.cs b/mROA.CodegenTools/DefineTemplateSection.cs index df97337..f80b799 100644 --- a/mROA.CodegenTools/DefineTemplateSection.cs +++ b/mROA.CodegenTools/DefineTemplateSection.cs @@ -2,7 +2,7 @@ using System; namespace mROA.CodegenTools { - public class DefineTemplateSection : ITemplateSection, ITagged + public class DefineTemplateSection : ITagged { public TemplateDocument Context { get; set; } public string StoredText { get; } @@ -18,14 +18,10 @@ namespace mROA.CodegenTools public string Tag => _tag; public int TargetLength => StoredText.Length; - public string Bake() - { - return String.Empty; - } public override string ToString() { - return StoredText; + return $"{nameof(_tag)}: {_tag}, {nameof(StoredText)}: {StoredText}"; } } } \ No newline at end of file diff --git a/mROA.CodegenTools/ITemplateSection.cs b/mROA.CodegenTools/ITemplateSection.cs index 5a27871..6aaa7dd 100644 --- a/mROA.CodegenTools/ITemplateSection.cs +++ b/mROA.CodegenTools/ITemplateSection.cs @@ -4,9 +4,14 @@ namespace mROA.CodegenTools { TemplateDocument Context { get; set; } int TargetLength { get; } - string Bake(); } + public interface IBaking + { + string Bake(); + } + + public interface ITagged : ITemplateSection { string Tag { get; } diff --git a/mROA.CodegenTools/InnerTemplateSection.cs b/mROA.CodegenTools/InnerTemplateSection.cs new file mode 100644 index 0000000..b7db33b --- /dev/null +++ b/mROA.CodegenTools/InnerTemplateSection.cs @@ -0,0 +1,20 @@ +namespace mROA.CodegenTools +{ + public class InnerTemplateSection : ITemplateSection, ITagged + { + private readonly string _tag; + public TemplateDocument Context { get; set; } + public int TargetLength => 0; + + public string Tag => _tag; + + public TemplateDocument InnerTemplate { get; } + + public InnerTemplateSection(string tag, TemplateDocument innerTemplate, TemplateDocument context) + { + _tag = tag; + Context = context; + InnerTemplate = innerTemplate; + } + } +} \ No newline at end of file diff --git a/mROA.CodegenTools/InsertTemplatePart.cs b/mROA.CodegenTools/InsertTemplatePart.cs index 50f6545..ecc58b2 100644 --- a/mROA.CodegenTools/InsertTemplatePart.cs +++ b/mROA.CodegenTools/InsertTemplatePart.cs @@ -1,9 +1,10 @@ using System; using System.Collections.Generic; +using System.Linq; namespace mROA.CodegenTools { - public class InsertTemplatePart : ITagged + public class InsertTemplatePart : ITagged, IBaking { private object _insertedValue; private string _tag; @@ -11,10 +12,10 @@ namespace mROA.CodegenTools public TemplateDocument Context { get; set; } public readonly List Parameters; - public InsertTemplatePart(string tag, List parameters, TemplateDocument context) + public InsertTemplatePart(string tag, TemplateDocument context, params string[] parameters) { _tag = tag; - Parameters = parameters; + Parameters = parameters.ToList(); Context = context; } @@ -61,7 +62,7 @@ namespace mROA.CodegenTools case string s: return s; default: - return ((ITemplateSection)_insertedValue).Bake(); + return ((ITemplateSection)_insertedValue).ToString(); } } } diff --git a/mROA.CodegenTools/LinkTemplateSection.cs b/mROA.CodegenTools/LinkTemplateSection.cs index 3d82159..0e883ff 100644 --- a/mROA.CodegenTools/LinkTemplateSection.cs +++ b/mROA.CodegenTools/LinkTemplateSection.cs @@ -2,7 +2,7 @@ using System.Linq; namespace mROA.CodegenTools { - public class LinkTemplateSection : ITemplateSection + public class LinkTemplateSection : ITemplateSection, IBaking { private readonly string _linkedTag; @@ -16,11 +16,23 @@ namespace mROA.CodegenTools public string LinkedTag => _linkedTag; - public int TargetLength { get; } + public int TargetLength + { + get + { + var attached = Context[_linkedTag]; + return attached?.TargetLength ?? 0; + } + } public string Bake() { - return Context[_linkedTag]?.Bake(); + return Context[_linkedTag]?.ToString(); + } + + public override string ToString() + { + return $"{nameof(LinkedTag)}: {_linkedTag}"; } } } \ No newline at end of file diff --git a/mROA.CodegenTools/LiteralTemplateSection.cs b/mROA.CodegenTools/LiteralTemplateSection.cs index ce23f28..e8e9704 100644 --- a/mROA.CodegenTools/LiteralTemplateSection.cs +++ b/mROA.CodegenTools/LiteralTemplateSection.cs @@ -1,6 +1,6 @@ namespace mROA.CodegenTools { - public class LiteralTemplateSection : ITemplateSection + public class LiteralTemplateSection : ITemplateSection, IBaking { private string _internalText; @@ -11,11 +11,11 @@ namespace mROA.CodegenTools } public TemplateDocument Context { get; set; } - public int TargetLength { get; } + public int TargetLength => _internalText.Length; public string Bake() { - return _internalText; + return ToString(); } public override string ToString() diff --git a/mROA.CodegenTools/ProgrammableTextSection.cs b/mROA.CodegenTools/ProgrammableTextSection.cs index de4bb61..99909d0 100644 --- a/mROA.CodegenTools/ProgrammableTextSection.cs +++ b/mROA.CodegenTools/ProgrammableTextSection.cs @@ -2,7 +2,7 @@ using System; namespace mROA.CodegenTools { - public class ProgrammableTextSection : ITemplateSection + public class ProgrammableTextSection : ITemplateSection, IBaking { public TemplateDocument Context { get; set; } public int TargetLength => 0; diff --git a/mROA.CodegenTools/Reading/DefineSectionReader.cs b/mROA.CodegenTools/Reading/DefineSectionReader.cs new file mode 100644 index 0000000..5d4f7e0 --- /dev/null +++ b/mROA.CodegenTools/Reading/DefineSectionReader.cs @@ -0,0 +1,24 @@ +using System; + +namespace mROA.CodegenTools +{ + public class DefineSectionReader : LeadingTextSectionReader + { + public DefineSectionReader() : base("", index, StringComparison.Ordinal); + var sectionName = GetTagValue(index, tagEnd); + tagEnd += 1; + var endIndex = TemplateText.IndexOf("", tagEnd, StringComparison.Ordinal); + var storedText = TemplateText.Substring(tagEnd, endIndex - tagEnd); + index = endIndex + 4; + PassCaretToCloseSymbol(); + PassCaretToCloseSymbol(); + return new DefineTemplateSection(storedText, sectionName, document); + } + } +} \ No newline at end of file diff --git a/mROA.CodegenTools/Reading/ISectionReader.cs b/mROA.CodegenTools/Reading/ISectionReader.cs new file mode 100644 index 0000000..0ed658e --- /dev/null +++ b/mROA.CodegenTools/Reading/ISectionReader.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace mROA.CodegenTools +{ + public interface ISectionReader + { + string TemplateText { get; set; } + int GetNextSectionIndex(int currentIndex); + ITemplateSection ExtractSection(ref int index, TemplateDocument document); + } +} \ No newline at end of file diff --git a/mROA.CodegenTools/Reading/InnerTemplateSectionReader.cs b/mROA.CodegenTools/Reading/InnerTemplateSectionReader.cs new file mode 100644 index 0000000..39cdefe --- /dev/null +++ b/mROA.CodegenTools/Reading/InnerTemplateSectionReader.cs @@ -0,0 +1,38 @@ +using System; + +namespace mROA.CodegenTools +{ + public class InnerTemplateSectionReader : LeadingTextSectionReader + { + public InnerTemplateSectionReader() : base("", start, StringComparison.Ordinal); + var innerStartSymbol = TemplateText.IndexOf("", _currentCaretPosition, StringComparison.Ordinal) + 1; + return _currentCaretPosition; + } + + public string TemplateText { get; set; } + + public int GetNextSectionIndex(int currentIndex) + { + _currentCaretPosition = Math.Max(currentIndex, _currentCaretPosition); + var index = TemplateText.IndexOf(_tagLeading, _currentCaretPosition, StringComparison.Ordinal); + _currentCaretPosition = index; + return index; + } + + public abstract ITemplateSection ExtractSection(ref int index, TemplateDocument document); + + protected string GetTagValue(int from, int to) + { + return TemplateText.Substring(from + 4, to - from - 5); + } + } +} \ No newline at end of file diff --git a/mROA.CodegenTools/Reading/LinkSectionReader.cs b/mROA.CodegenTools/Reading/LinkSectionReader.cs new file mode 100644 index 0000000..fece788 --- /dev/null +++ b/mROA.CodegenTools/Reading/LinkSectionReader.cs @@ -0,0 +1,20 @@ +namespace mROA.CodegenTools +{ + public class LinkSectionReader : LeadingTextSectionReader + { + public LinkSectionReader() : base(" ReaderTypes = new List + { + typeof(DefineSectionReader), + typeof(InsertSectionReader), + typeof(LinkSectionReader), + typeof(InnerTemplateSectionReader) + }; + + public static TemplateDocument Parce(string templateText) + { + + int currentIndex = 0; + var activeReaders = new List(); + + foreach (var readerType in ReaderTypes) + { + var reader = Activator.CreateInstance(readerType) as ISectionReader; + reader.TemplateText = templateText; + activeReaders.Add(reader); + } + + var doc = new TemplateDocument(); + + while (currentIndex < templateText.Length) + { + List<(ISectionReader reader, int index)> indices = activeReaders.Select(i => ((ISectionReader Readers, int index))(i, i.GetNextSectionIndex(currentIndex))).Where(i => i.index > -1).ToList(); + int minIndex = templateText.Length; + ISectionReader minReader = null; + if (indices.Count != 0) + { + minIndex = indices.Min(i => i.index); + minReader = indices.FirstOrDefault(i => i.index == minIndex).reader; + + if (indices.Count != activeReaders.Count) + { + activeReaders = indices.Select(i => i.reader).ToList(); + } + } + + + if (currentIndex != minIndex) + { + var literalText = templateText.Substring(currentIndex, minIndex - currentIndex); + var literal = + new LiteralTemplateSection(literalText, doc); + doc.Parts.Add(literal); + currentIndex = minIndex; + } + + if (indices.Count != 0) + { + var section = minReader.ExtractSection(ref currentIndex, doc); + doc.Parts.Add(section); + } + + + } + + return doc; + } + } +} \ No newline at end of file diff --git a/mROA.CodegenTools/TemplateDocument.cs b/mROA.CodegenTools/TemplateDocument.cs index 19f2513..cb00d52 100644 --- a/mROA.CodegenTools/TemplateDocument.cs +++ b/mROA.CodegenTools/TemplateDocument.cs @@ -6,7 +6,7 @@ namespace mROA.CodegenTools { public class TemplateDocument { - public List Parts { get; } + public List Parts { get; set; } = new List(); public object AdditionalContext { get; set; } public ITagged this[string tag] => Parts.OfType().FirstOrDefault(i => i.Tag == tag); public void Insert(string tag, object value) @@ -22,10 +22,9 @@ namespace mROA.CodegenTools { var approximatelyLength = Parts.Sum(i => i.TargetLength); var stringBuilder = new StringBuilder(approximatelyLength); - - for (int i = 0; i < Parts.Count; i++) + + foreach (var part in Parts.OfType()) { - var part = Parts[i]; var baked = part.Bake(); stringBuilder.Append(baked); } diff --git a/mROA.sln b/mROA.sln index 6ca35dc..aac4a31 100644 --- a/mROA.sln +++ b/mROA.sln @@ -33,6 +33,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.Events.Client", "Ex EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mROA.CodegenTools", "mROA.CodegenTools\mROA.CodegenTools.csproj", "{2A2821B7-E5C5-443A-9801-9622493594A0}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Codegen", "Codegen", "{3DB22457-E65B-426F-B3DD-08C615132B3E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicDemo", "BasicDemo\BasicDemo.csproj", "{87396E86-D7ED-4556-AB50-F3696FEF9072}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -87,6 +91,10 @@ Global {2A2821B7-E5C5-443A-9801-9622493594A0}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A2821B7-E5C5-443A-9801-9622493594A0}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A2821B7-E5C5-443A-9801-9622493594A0}.Release|Any CPU.Build.0 = Release|Any CPU + {87396E86-D7ED-4556-AB50-F3696FEF9072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87396E86-D7ED-4556-AB50-F3696FEF9072}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87396E86-D7ED-4556-AB50-F3696FEF9072}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87396E86-D7ED-4556-AB50-F3696FEF9072}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -100,5 +108,7 @@ Global {6342C7FC-12B4-4BC6-BA25-159B1400D952} = {032E1288-4D26-4FA5-ABB6-E7D738F319DE} {B63F58B2-8D86-42F3-96A5-470CB449BFD3} = {032E1288-4D26-4FA5-ABB6-E7D738F319DE} {98451C0E-E179-4F5F-9F1A-8B353EDE2EBC} = {032E1288-4D26-4FA5-ABB6-E7D738F319DE} + {3DB22457-E65B-426F-B3DD-08C615132B3E} = {EAE92F5A-664C-41AB-8811-5885524B5347} + {87396E86-D7ED-4556-AB50-F3696FEF9072} = {3DB22457-E65B-426F-B3DD-08C615132B3E} EndGlobalSection EndGlobal