Пример #1
0
        /// <summary>
        /// Add text as lg file content to template engine. A fullpath id is needed when importResolver is empty, or simply pass in customized importResolver.
        /// </summary>
        /// <param name="content">Text content contains lg templates.</param>
        /// <param name="id">id is the content identifier. If importResolver is null, id must be a full path string. </param>
        /// <param name="importResolver">resolver to resolve LG import id to template text.</param>
        /// <returns>Template engine with the parsed content.</returns>
        public TemplateEngine AddText(string content, string id = "", ImportResolverDelegate importResolver = null)
        {
            CheckImportResolver(id, importResolver);

            var rootResource = LGParser.Parse(content, id);
            var lgresources  = rootResource.DiscoverDependencies(importResolver);

            Templates.AddRange(lgresources.SelectMany(x => x.Templates));
            RunStaticCheck(Templates);

            return(this);
        }
Пример #2
0
        /// <summary>
        /// Add a new template and return LG resource.
        /// </summary>
        /// <param name="templateName">new template name.</param>
        /// <param name="parameters">new params.</param>
        /// <param name="templateBody">new  template body.</param>
        /// <returns>new lg resource.</returns>
        public LGResource AddTemplate(string templateName, List <string> parameters, string templateBody)
        {
            var template = Templates.FirstOrDefault(u => u.Name == templateName);

            if (template != null)
            {
                throw new Exception($"template {templateName} already exists.");
            }

            var templateNameLine = BuildTemplateNameLine(templateName, parameters);
            var newTemplateBody  = ConvertTemplateBody(templateBody);
            var newContent       = $"{Content}\r\n{templateNameLine}\r\n{newTemplateBody}";

            return(LGParser.Parse(newContent, Id));
        }
Пример #3
0
        /// <summary>
        /// Delete an exist template.
        /// </summary>
        /// <param name="templateName">which template should delete.</param>
        /// <returns>updated LG file.</returns>
        public LGFile DeleteTemplate(string templateName)
        {
            var template = Templates.FirstOrDefault(u => u.Name == templateName);

            if (template != null)
            {
                var startLine = template.ParseTree.Start.Line - 1;
                var stopLine  = template.ParseTree.Stop.Line - 1;

                var newContent = ReplaceRangeContent(Content, startLine, stopLine, null);
                Initialize(LGParser.ParseText(newContent, Id, ImportResolver));
            }

            return(this);
        }
Пример #4
0
        /// <summary>
        /// Delete an exist template.
        /// </summary>
        /// <param name="templateName">which template should delete.</param>
        /// <returns>return the new lg resource.</returns>
        public LGResource DeleteTemplate(string templateName)
        {
            var template = Templates.FirstOrDefault(u => u.Name == templateName);

            if (template == null)
            {
                return(this);
            }

            var startLine = template.ParseTree.Start.Line - 1;
            var stopLine  = template.ParseTree.Stop.Line - 1;

            var newContent = ReplaceRangeContent(Content, startLine, stopLine, null);

            return(LGParser.Parse(newContent, Id));
        }
Пример #5
0
        /// <summary>
        /// Add a new template and return LG File.
        /// </summary>
        /// <param name="templateName">new template name.</param>
        /// <param name="parameters">new params.</param>
        /// <param name="templateBody">new  template body.</param>
        /// <returns>updated LG file.</returns>
        public LGFile AddTemplate(string templateName, List <string> parameters, string templateBody)
        {
            var template = Templates.FirstOrDefault(u => u.Name == templateName);

            if (template != null)
            {
                throw new Exception(LGErrors.TemplateExist(templateName));
            }

            var templateNameLine = BuildTemplateNameLine(templateName, parameters);
            var newTemplateBody  = ConvertTemplateBody(templateBody);
            var newContent       = $"{Content.TrimEnd()}\r\n\r\n{templateNameLine}\r\n{newTemplateBody}\r\n";

            Initialize(LGParser.ParseText(newContent, Id, ImportResolver));

            return(this);
        }
Пример #6
0
        /// <summary>
        /// Use to evaluate an inline template str.
        /// </summary>
        /// <param name="inlineStr">inline string which will be evaluated.</param>
        /// <param name="scope">scope object or JToken.</param>
        /// <returns>Evaluate result.</returns>
        public object Evaluate(string inlineStr, object scope = null)
        {
            // wrap inline string with "# name and -" to align the evaluation process
            var fakeTemplateId = "__temp__";

            inlineStr = !inlineStr.Trim().StartsWith("```") && inlineStr.IndexOf('\n') >= 0
                   ? "```" + inlineStr + "```" : inlineStr;
            var wrappedStr = $"# {fakeTemplateId} \r\n - {inlineStr}";

            var lgsource  = LGParser.Parse(wrappedStr, "inline");
            var templates = Templates.Concat(lgsource.Templates).ToList();

            RunStaticCheck(templates);

            var evaluator = new Evaluator(templates, this.expressionEngine);

            return(evaluator.EvaluateTemplate(fakeTemplateId, scope));
        }
Пример #7
0
        /// <summary>
        /// update an exist template.
        /// </summary>
        /// <param name="templateName">origin template name. the only id of a template.</param>
        /// <param name="newTemplateName">new template Name.</param>
        /// <param name="parameters">new params.</param>
        /// <param name="templateBody">new template body.</param>
        /// <returns>updated LG file.</returns>
        public LGFile UpdateTemplate(string templateName, string newTemplateName, List <string> parameters, string templateBody)
        {
            var template = Templates.FirstOrDefault(u => u.Name == templateName);

            if (template != null)
            {
                var templateNameLine = BuildTemplateNameLine(newTemplateName, parameters);
                var newTemplateBody  = ConvertTemplateBody(templateBody);
                var content          = $"{templateNameLine}\r\n{newTemplateBody}\r\n";
                var startLine        = template.ParseTree.Start.Line - 1;
                var stopLine         = template.ParseTree.Stop.Line - 1;

                var newContent = ReplaceRangeContent(Content, startLine, stopLine, content);
                Initialize(LGParser.ParseText(newContent, Id, ImportResolver));
            }

            return(this);
        }
Пример #8
0
        /// <summary>
        /// update an exist template.
        /// </summary>
        /// <param name="templateName">origin template name. the only id of a template.</param>
        /// <param name="parameters">new params.</param>
        /// <param name="templateBody">new template body.</param>
        /// <returns>new LG resource.</returns>
        public LGResource UpdateTemplate(string templateName, List <string> parameters, string templateBody)
        {
            var template = Templates.FirstOrDefault(u => u.Name == templateName);

            if (template == null)
            {
                return(this);
            }

            var templateNameLine = BuildTemplateNameLine(templateName, parameters);
            var newTemplateBody  = ConvertTemplateBody(templateBody);
            var content          = $"{templateNameLine}\r\n{newTemplateBody}";
            var startLine        = template.ParseTree.Start.Line - 1;
            var stopLine         = template.ParseTree.Stop.Line - 1;

            var newContent = ReplaceRangeContent(Content, startLine, stopLine, content);

            return(LGParser.Parse(newContent, Id));
        }
Пример #9
0
        /// <summary>
        /// Load .lg files into template engine
        /// You can add one file, or mutlple file as once
        /// If you have multiple files referencing each other, make sure you add them all at once,
        /// otherwise static checking won't allow you to add it one by one.
        /// </summary>
        /// <param name="filePaths">Paths to .lg files.</param>
        /// <param name="importResolver">resolver to resolve LG import id to template text.</param>
        /// <returns>Teamplate engine with parsed files.</returns>
        public TemplateEngine AddFiles(IEnumerable <string> filePaths, ImportResolverDelegate importResolver = null)
        {
            var totalLGResources = new List <LGResource>();

            foreach (var filePath in filePaths)
            {
                var fullPath     = Path.GetFullPath(ImportResolver.NormalizePath(filePath));
                var rootResource = LGParser.Parse(File.ReadAllText(fullPath), fullPath);
                var lgresources  = rootResource.DiscoverDependencies(importResolver);
                totalLGResources.AddRange(lgresources);
            }

            // Remove duplicated lg files by id
            var deduplicatedLGResources = totalLGResources.GroupBy(x => x.Id).Select(x => x.First()).ToList();

            Templates.AddRange(deduplicatedLGResources.SelectMany(x => x.Templates));
            RunStaticCheck(Templates);

            return(this);
        }
Пример #10
0
        public List <Diagnostic> CheckFiles(IEnumerable <string> filePaths, ImportResolverDelegate importResolver = null)
        {
            var result         = new List <Diagnostic>();
            var templates      = new List <LGTemplate>();
            var isParseSuccess = true;

            try
            {
                var totalLGResources = new List <LGResource>();
                foreach (var filePath in filePaths)
                {
                    // do not use ??=, it will cause issue in the C# < 8.0
                    importResolver = importResolver ?? ImportResolver.FileResolver;

                    var fullPath     = Path.GetFullPath(ImportResolver.NormalizePath(filePath));
                    var rootResource = LGParser.Parse(File.ReadAllText(fullPath), fullPath);
                    var resources    = rootResource.DiscoverDependencies(importResolver);
                    totalLGResources.AddRange(resources);
                }

                var deduplicatedLGResources = totalLGResources.GroupBy(x => x.Id).Select(x => x.First()).ToList();
                templates = deduplicatedLGResources.SelectMany(x => x.Templates).ToList();
            }
            catch (LGException ex)
            {
                result.AddRange(ex.Diagnostics);
                isParseSuccess = false;
            }
            catch (Exception err)
            {
                result.Add(new Diagnostic(new Range(new Position(0, 0), new Position(0, 0)), err.Message));
                isParseSuccess = false;
            }

            if (isParseSuccess)
            {
                result.AddRange(CheckTemplates(templates));
            }

            return(result);
        }
Пример #11
0
        public List <Diagnostic> CheckText(string content, string id = "", ImportResolverDelegate importResolver = null)
        {
            if (importResolver == null)
            {
                var importPath = ImportResolver.NormalizePath(id);
                if (!Path.IsPathRooted(importPath))
                {
                    throw new Exception("[Error] id must be full path when importResolver is null");
                }
            }

            var result         = new List <Diagnostic>();
            var templates      = new List <LGTemplate>();
            var isParseSuccess = true;

            try
            {
                var rootResource = LGParser.Parse(content, id);
                var resources    = rootResource.DiscoverDependencies(importResolver);
                templates = resources.SelectMany(x => x.Templates).ToList();
            }
            catch (LGException ex)
            {
                result.AddRange(ex.Diagnostics);
                isParseSuccess = false;
            }
            catch (Exception err)
            {
                result.Add(new Diagnostic(new Range(new Position(0, 0), new Position(0, 0)), err.Message));
                isParseSuccess = false;
            }

            if (isParseSuccess)
            {
                result.AddRange(CheckTemplates(templates));
            }

            return(result);
        }
Пример #12
0
        /// <summary>
        /// Use to evaluate an inline template str.
        /// </summary>
        /// <param name="inlineStr">inline string which will be evaluated.</param>
        /// <param name="scope">scope object or JToken.</param>
        /// <returns>Evaluate result.</returns>
        public object Evaluate(string inlineStr, object scope = null)
        {
            if (inlineStr == null)
            {
                throw new ArgumentException("inline string is null.");
            }

            CheckErrors();

            // wrap inline string with "# name and -" to align the evaluation process
            var fakeTemplateId = Guid.NewGuid().ToString();
            var multiLineMark  = "```";

            inlineStr = !inlineStr.Trim().StartsWith(multiLineMark) && inlineStr.Contains('\n')
                   ? $"{multiLineMark}{inlineStr}{multiLineMark}" : inlineStr;

            var newContent = $"# {fakeTemplateId} \r\n - {inlineStr}";

            var newLgFile = LGParser.ParseTextWithRef(newContent, this);

            return(newLgFile.EvaluateTemplate(fakeTemplateId, scope));
        }
Пример #13
0
        /// <summary>
        /// Resolve imported LG resources from a start resource.
        /// All the imports will be visited and resolved to LGResouce list.
        /// </summary>
        /// <param name="start">The lg resource from which to start resolving imported resources.</param>
        /// <param name="importResolver">resolver to resolve LG import id to template text.</param>
        /// <param name="resourcesFound">Resources that have been found.</param>
        private void ResolveImportResources(LGResource start, ImportResolverDelegate importResolver, HashSet <LGResource> resourcesFound)
        {
            var resourceIds = start.Imports.Select(lg => lg.Id).ToList();

            resourcesFound.Add(start);

            foreach (var id in resourceIds)
            {
                try
                {
                    var(content, path) = importResolver(start.Id, id);
                    var childResource = LGParser.Parse(content, path);
                    if (!resourcesFound.Contains(childResource))
                    {
                        ResolveImportResources(childResource, importResolver, resourcesFound);
                    }
                }
                catch (Exception err)
                {
                    throw new Exception($"[Error]{id}:{err.Message}", err);
                }
            }
        }