Как передать несколько параметров в подшаблон на StringTemplate4 - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь вызвать подшаблон, где мне нужно передать два выражения в качестве параметра и обработать этот параметр с помощью CustomRenderer.

При вызове подшаблона + CustomRenderer с одним параметром это делается путем вызова метода из контекста шаблона, как показано ниже.

Мой вопрос: как я могу вызвать, например,

$concat2values(context.Value, "Literal")$

заданный контекст. Значение - это строка «somevalue» и в результате получить

somevalueLiteral

obs .: меня беспокоит то, что CustomRenderer просто обнаруживает один параметр объекта, и без всяких попыток я мог бы построить шаблон таким образом. Моя цель - перехватить обработанный код из скрипта обратно в "Engine", который его обрабатывает.

templategroup.stg

group mygroup;

delimiters "$","$"

main(context) ::= <<
$formatSomething(context.Value)$
>>

formatSomething(value) ::= <<
$value; format = "_formatSomething_"$
>>

myformater.cs

using Antlr4.StringTemplate;
using System;
using System.Globalization;
using System.Linq;

namespace Engine.Components.Engine.Formatters
{
    public class SomeFormatter: StringRenderer
    {
        public override string ToString(object o, string formatString, CultureInfo culture)
        {
            if ("_formatSomething_".Equals(formatString))
                return FormatSomething(o);
            return base.ToString(o, formatString, culture);
        }

        private string FormatSomething(object o)
        {
            ** DO STUFF **
            string result = do_stuff_and_return_it_formatted();
            return result;
        }
    }
}

mytemplateengine.cs

private string ProcessTemplate<T>(string fullPathTemplateFileName, T context)
{
    try
    {
        var templateSource = File.ReadAllText(fullPathTemplateFileName);
        var groupTemplate = CreateTemplateGroup(templateSource);

        var templates = new TemplateGroupString(groupTemplate);
        // vvvvvvv----- SHOULD I USE OBJECT OR ANOTHER SPECIFIC TYPE TO THE TASK?
        templates.RegisterRenderer(typeof(object), new SomeFormatter());      
        var engine = templates.GetInstanceOf("main");

        if (engine == null)
            throw new Exception($"Failed to get template {fullPathTemplateFileName}");

        engine.Add("context", context);

        return engine.Render();
    }
    catch (Exception ex)
    {
        Errors.Add($"{ex.Message}{ex.StackTrace}");
        return $"{ex.Message}{ex.StackTrace}";
    }
}
...