Inheritance: DfmFencesToken
Example #1
0
        public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context)
        {
            if (!PathUtility.IsRelativePath(token.Path))
            {
                string errorMessage = $"Code absolute path: {token.Path} is not supported in file {context.GetFilePathStack().Peek()}";
                Logger.LogError(errorMessage);
                return(DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, errorMessage));
            }

            try
            {
                // TODO: Valid REST and REST-i script.
                var fencesPath    = Path.Combine(context.GetBaseFolder(), (RelativePath)context.GetFilePathStack().Peek() + (RelativePath)token.Path);
                var extractResult = _dfmCodeExtractor.ExtractFencesCode(token, fencesPath);
                return(DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, extractResult.ErrorMessage, extractResult.FencesCodeLines));
            }
            catch (DirectoryNotFoundException)
            {
                return(DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token));
            }
            catch (FileNotFoundException)
            {
                return(DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token));
            }
        }
Example #2
0
        public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, IMarkdownContext context)
        {
            if (!PathUtility.IsRelativePath(token.Path))
            {
                string errorMessage = $"Code absolute path: {token.Path} is not supported in file {context.GetFilePathStack().Peek()}";
                Logger.LogError(errorMessage);
                return(DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, errorMessage));
            }

            try
            {
                // Always report original dependency
                context.ReportDependency(token.Path);
                var filePathWithStatus = DfmFallbackHelper.GetFilePathWithFallback(token.Path, context);
                var extractResult      = _dfmCodeExtractor.ExtractFencesCode(token, filePathWithStatus.Item1);
                var result             = DfmFencesBlockHelper.GetRenderedFencesBlockString(token, renderer.Options, extractResult.ErrorMessage, extractResult.FencesCodeLines);
                return(result);
            }
            catch (DirectoryNotFoundException)
            {
                return(DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token));
            }
            catch (FileNotFoundException)
            {
                return(DfmFencesBlockHelper.GenerateReferenceNotFoundErrorMessage(renderer, token));
            }
        }
Example #3
0
        public virtual StringBuffer RenderFencesFromCodeContent(string codeContent, DfmFencesBlockToken token)
        {
            if (codeContent == null)
            {
                return(RenderCodeErrorString($"{nameof(codeContent)} can not be null"));
            }

            if (string.IsNullOrEmpty(token.Path))
            {
                return(RenderCodeErrorString($"{nameof(token.Path)} can not been null or empty"));
            }

            if (token.QueryStringAndFragment != null && token.QueryStringAndFragment.Length == 1)
            {
                return(RenderCodeErrorString($"Length of {nameof(token.QueryStringAndFragment)} can not be 1"));
            }

            var fencesCode = codeContent.Replace("\r\n", "\n").Split('\n');

            var pathQueryOption = _dfmCodeExtractor.ParsePathQueryString(token.QueryStringAndFragment);

            var code = ExtractCode(token, fencesCode, pathQueryOption);

            return(RenderFencesCode(token, new Options {
                ShouldExportSourceInfo = false
            }, code.ErrorMessage, code.CodeLines, pathQueryOption));
        }
Example #4
0
        public virtual StringBuffer RenderFencesFromCodeContent(string codeContent, string path, string queryStringAndFragment = null, string name = null, string lang = null, string title = null)
        {
            if (codeContent == null)
            {
                return(RenderCodeErrorString($"{nameof(codeContent)} can not be null"));
            }

            if (string.IsNullOrEmpty(path))
            {
                return(RenderCodeErrorString($"{nameof(path)} can not been null or empty"));
            }

            if (queryStringAndFragment != null && queryStringAndFragment.Length == 1)
            {
                return(RenderCodeErrorString($"Length of {nameof(queryStringAndFragment)} can not be 1"));
            }

            var pathQueryOption =
                !string.IsNullOrEmpty(queryStringAndFragment)
                    ? DfmFencesRule.ParsePathQueryString(queryStringAndFragment.Remove(1), queryStringAndFragment.Substring(1), true)
                    : null;

            var token = new DfmFencesBlockToken(null, null, name, path, new SourceInfo(), lang, title, pathQueryOption, queryStringAndFragment);

            var fencesCode = codeContent.Replace("\r\n", "\n").Split('\n');
            var code       = ExtractCode(token, fencesCode);

            return(RenderFencesCode(token, new Options {
                ShouldExportSourceInfo = false
            }, code.ErrorMessage, code.CodeLines));
        }
Example #5
0
        public DfmExtractCodeResult ExtractFencesCode(DfmFencesBlockToken token, string fencesPath)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            if (string.IsNullOrEmpty(fencesPath))
            {
                throw new ArgumentNullException(nameof(fencesPath));
            }

            var fencesCode = File.ReadAllLines(fencesPath);

            // NOTE: Parsing language and removing comment lines only do for tag name representation
            if (token.PathQueryOption?.TagName != null)
            {
                var   lang = GetCodeLanguageOrExtension(token);
                Regex regex;
                if (!CodeLanguageRegexes.TryGetValue(lang, out regex))
                {
                    string errorMessage = $"{lang} is not supported languaging name, alias or extension for parsing code snippet with tag name, you can use line numbers instead";
                    Logger.LogError(errorMessage);
                    return(new DfmExtractCodeResult {
                        IsSuccessful = false, ErrorMessage = errorMessage, FencesCodeLines = fencesCode
                    });
                }

                var resolveResult = ResolveTagNamesFromPath(fencesPath, fencesCode, token.PathQueryOption.TagName, regex);
                if (!resolveResult.IsSuccessful)
                {
                    Logger.LogError(resolveResult.ErrorMessage);
                    return(new DfmExtractCodeResult {
                        IsSuccessful = false, ErrorMessage = resolveResult.ErrorMessage, FencesCodeLines = fencesCode
                    });
                }

                return(GetFencesCodeCore(fencesCode, resolveResult.StartLine, resolveResult.EndLine, resolveResult.IndentLength, resolveResult.ExcludesLines));
            }
            else
            {
                // line range check only need to be done for line number representation
                string errorMessage;
                if (!CheckLineRange(fencesCode.Length, token.PathQueryOption?.StartLine, token.PathQueryOption?.EndLine, out errorMessage))
                {
                    Logger.LogError(errorMessage);
                    return(new DfmExtractCodeResult {
                        IsSuccessful = false, ErrorMessage = errorMessage, FencesCodeLines = fencesCode
                    });
                }

                int startLine    = token.PathQueryOption?.StartLine ?? 1;
                int endLine      = token.PathQueryOption?.EndLine ?? fencesCode.Length;
                int indentLength = (from line in fencesCode.Skip(startLine - 1).Take(endLine - startLine + 1)
                                    where !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line)
                                    select(int?) GetIndentLength(line)).Min() ?? 0;
                return(GetFencesCodeCore(fencesCode, startLine, endLine, indentLength));
            }
        }
Example #6
0
        public DfmExtractCodeResult ExtractFencesCode(DfmFencesBlockToken token, string fencesPath)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            if (string.IsNullOrEmpty(fencesPath))
            {
                throw new ArgumentNullException(nameof(fencesPath));
            }

            var fencesCode = File.ReadAllLines(fencesPath);

            if (token.PathQueryOption == null)
            {
                // Add the full file when no query option is given
                return(new DfmExtractCodeResult {
                    IsSuccessful = true, FencesCodeLines = fencesCode
                });
            }

            if (!token.PathQueryOption.ValidateAndPrepare(fencesCode, token))
            {
                Logger.LogError(token.PathQueryOption.ErrorMessage);
                return(new DfmExtractCodeResult {
                    IsSuccessful = false, ErrorMessage = token.PathQueryOption.ErrorMessage, FencesCodeLines = fencesCode
                });
            }

            var includedLines = new List <string>();

            foreach (var line in token.PathQueryOption.GetQueryLines(fencesCode))
            {
                includedLines.Add(line);
            }

            if (!token.PathQueryOption.ValidateHighlightLinesAndDedentLength(includedLines.Count))
            {
                Logger.LogWarning(token.PathQueryOption.ErrorMessage);
            }

            var dedentLength = token.PathQueryOption.DedentLength ??
                               (from line in includedLines
                                where !string.IsNullOrEmpty(line) && !string.IsNullOrWhiteSpace(line)
                                select(int?) DfmCodeExtractorHelper.GetIndentLength(line)).Min() ?? 0;

            return(new DfmExtractCodeResult
            {
                IsSuccessful = true,
                ErrorMessage = token.PathQueryOption.ErrorMessage,
                FencesCodeLines = (dedentLength == 0 ? includedLines : includedLines.Select(s => Regex.Replace(s, string.Format(RemoveIndentSpacesRegexString, dedentLength), string.Empty))).ToArray()
            });
        }
        public override bool ValidateAndPrepare(string[] lines, DfmFencesBlockToken token)
        {
            foreach (var pair in LinePairs)
            {
                if (!CheckLineRange(lines.Length, pair.Item1, pair.Item2))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #8
0
        public DfmExtractCodeResult ExtractFencesCode(DfmFencesBlockToken token, string fencesPath)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            if (string.IsNullOrEmpty(fencesPath))
            {
                throw new ArgumentNullException(nameof(fencesPath));
            }

            var fencesCode = File.ReadAllLines(fencesPath);

            // NOTE: Parsing language and removing comment lines only do for tag name representation
            if (token.PathQueryOption?.TagName != null)
            {
                var lang = GetCodeLanguageOrExtension(token);
                Regex regex;
                if (!CodeLanguageRegexes.TryGetValue(lang, out regex))
                {
                    string errorMessage = $"{lang} is not supported languaging name, alias or extension for parsing code snippet with tag name, you can use line numbers instead";
                    Logger.LogError(errorMessage);
                    return new DfmExtractCodeResult { IsSuccessful = false, ErrorMessage = errorMessage, FencesCodeLines = fencesCode };
                }

                var resolveResult = ResolveTagNamesFromPath(fencesPath, fencesCode, token.PathQueryOption.TagName, regex);
                if (!resolveResult.IsSuccessful)
                {
                    Logger.LogError(resolveResult.ErrorMessage);
                    return new DfmExtractCodeResult { IsSuccessful = false, ErrorMessage = resolveResult.ErrorMessage, FencesCodeLines = fencesCode };
                }

                return GetFencesCodeCore(fencesCode, resolveResult.StartLine, resolveResult.EndLine, resolveResult.ExcludesLines);
            }
            else
            {
                // line range check only need to be done for line number representation
                string errorMessage;
                if (!CheckLineRange(fencesCode.Length, token.PathQueryOption?.StartLine, token.PathQueryOption?.EndLine, out errorMessage))
                {
                    Logger.LogError(errorMessage);
                    return new DfmExtractCodeResult { IsSuccessful = false, ErrorMessage = errorMessage, FencesCodeLines = fencesCode };
                }

                return GetFencesCodeCore(fencesCode, token.PathQueryOption?.StartLine, token.PathQueryOption?.EndLine);
            }
        }
Example #9
0
        public static string GetRenderedFencesBlockString(DfmFencesBlockToken token, Options options, string errorMessage, string[] codeLines = null)
        {
            string renderedErrorMessage = string.Empty;
            string renderedCodeLines = string.Empty;
            if (!string.IsNullOrEmpty(errorMessage))
            {
                renderedErrorMessage = $@"<!-- {StringHelper.HtmlEncode(errorMessage)} -->\n";
            }

            if (codeLines != null)
            {
                var lang = string.IsNullOrEmpty(token.Lang) ? null : $" class=\"{options.LangPrefix}{token.Lang}\"";
                var name = string.IsNullOrEmpty(token.Name) ? null : $" name=\"{StringHelper.HtmlEncode(token.Name)}\"";
                var title = string.IsNullOrEmpty(token.Title) ? null : $" title=\"{StringHelper.HtmlEncode(token.Title)}\"";

                renderedCodeLines = $"<pre><code{lang}{name}{title}>{StringHelper.HtmlEncode(string.Join("\n", codeLines))}\n</code></pre>";
            }

            return $"{renderedErrorMessage}{renderedCodeLines}";
        }
Example #10
0
        public static string GetRenderedFencesBlockString(DfmFencesBlockToken token, Options options, string errorMessage, string[] codeLines = null)
        {
            string renderedErrorMessage = string.Empty;
            string renderedCodeLines    = string.Empty;

            if (!string.IsNullOrEmpty(errorMessage))
            {
                renderedErrorMessage = $@"<!-- {StringHelper.HtmlEncode(errorMessage)} -->\n";
            }

            if (codeLines != null)
            {
                var lang  = string.IsNullOrEmpty(token.Lang) ? null : $" class=\"{options.LangPrefix}{token.Lang}\"";
                var name  = string.IsNullOrEmpty(token.Name) ? null : $" name=\"{StringHelper.HtmlEncode(token.Name)}\"";
                var title = string.IsNullOrEmpty(token.Title) ? null : $" title=\"{StringHelper.HtmlEncode(token.Title)}\"";

                renderedCodeLines = $"<pre><code{lang}{name}{title}>{StringHelper.HtmlEncode(string.Join("\n", codeLines))}\n</code></pre>";
            }

            return($"{renderedErrorMessage}{renderedCodeLines}");
        }
        public override bool ValidateAndPrepare(string[] lines, DfmFencesBlockToken token)
        {
            // NOTE: Parsing language and removing comment lines only do for tag name representation
            var lang = GetCodeLanguageOrExtension(token);
            List <ICodeSnippetExtractor> extractors;

            if (!CodeLanguageExtractors.TryGetValue(lang, out extractors))
            {
                ErrorMessage = $"{lang} is not supported languaging name, alias or extension for parsing code snippet with tag name, you can use line numbers instead";
                return(false);
            }

            resolveResult = ResolveTagNamesFromPath(token.Path, lines, TagName, extractors);
            if (!resolveResult.IsSuccessful)
            {
                ErrorMessage = resolveResult.ErrorMessage;
                return(false);
            }

            return(true);
        }
Example #12
0
        public static string GenerateReferenceNotFoundErrorMessage(IMarkdownRenderer renderer, DfmFencesBlockToken token)
        {
            var errorMessageInMarkdown = $"Can not find reference {token.Path}";
            var errorMessage           = $"Unable to resolve {token.SourceInfo.Markdown}. {errorMessageInMarkdown}. at line {token.SourceInfo.LineNumber}.";

            Logger.LogError(errorMessage);
            return(GetRenderedFencesBlockString(token, renderer.Options, errorMessageInMarkdown));
        }
Example #13
0
        public static string GenerateReferenceNotFoundErrorMessage(IMarkdownRenderer renderer, DfmFencesBlockToken token)
        {
            string errorMessage = $"Can not find reference {token.Path}";

            Logger.LogError(errorMessage);
            return(GetRenderedFencesBlockString(token, renderer.Options, errorMessage));
        }
Example #14
0
 public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context)
 {
     return Render(renderer, token, (IMarkdownContext)context);
 }
Example #15
0
 private static string GetCodeLanguageOrExtension(DfmFencesBlockToken token)
 {
     return !string.IsNullOrEmpty(token.Lang) ? token.Lang : Path.GetExtension(token.Path);
 }
Example #16
0
 public static string GenerateReferenceNotFoundErrorMessage(IMarkdownRenderer renderer, DfmFencesBlockToken token)
     => GenerateReferenceNotFoundErrorMessage(renderer, (DfmFencesToken)token);
Example #17
0
 public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context)
 {
     return Insert(token, ExposeTokenNameInDfm(token));
 }
 public override bool ValidateAndPrepare(string[] lines, DfmFencesBlockToken token)
 {
     return(CheckLineRange(lines.Length, StartLine, EndLine));
 }
Example #19
0
 private static string GetCodeLanguageOrExtension(DfmFencesBlockToken token)
 {
     return(!string.IsNullOrEmpty(token.Lang) ? token.Lang : Path.GetExtension(token.Path));
 }
Example #20
0
 public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context)
 {
     return(Render(renderer, token, (IMarkdownContext)context));
 }
Example #21
0
 public override bool ValidateAndPrepare(string[] lines, DfmFencesBlockToken token)
 {
     return(true);
 }
Example #22
0
 private static StringBuffer GenerateReferenceNotFoundErrorMessage(IMarkdownRenderer renderer, DfmFencesBlockToken token)
 {
     string errorMessage = $"Can not find reference {token.Path}";
     Logger.LogError(errorMessage);
     return DfmRendererHelper.GetRenderedFencesBlockString(token, renderer.Options, errorMessage);
 }
Example #23
0
        public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context)
        {
            if (!PathUtility.IsRelativePath(token.Path))
            {
                string errorMessage = $"Code absolute path: {token.Path} is not supported in file {context.GetFilePathStack().Peek()}";
                Logger.LogError(errorMessage);
                return DfmRendererHelper.GetRenderedFencesBlockString(token, renderer.Options, errorMessage);
            }

            try
            {
                // TODO: Valid REST and REST-i script.
                var fencesPath = ((RelativePath)token.Path).BasedOn((RelativePath)context.GetFilePathStack().Peek());
                var extractResult = _dfmCodeExtractor.ExtractFencesCode(token, fencesPath);
                return DfmRendererHelper.GetRenderedFencesBlockString(token, renderer.Options, extractResult.ErrorMessage, extractResult.FencesCodeLines);
            }
            catch (FileNotFoundException)
            {
                string errorMessage = $"Can not find reference {token.Path}";
                Logger.LogError(errorMessage);
                return DfmRendererHelper.GetRenderedFencesBlockString(token, renderer.Options, errorMessage);
            }
        }
Example #24
0
 public static string GetRenderedFencesBlockString(DfmFencesBlockToken token, Options options,
                                                   string errorMessage, string[] codeLines = null)
 => GetRenderedFencesBlockString((DfmFencesToken)token, options, errorMessage, codeLines);
Example #25
0
 public static string GenerateReferenceNotFoundErrorMessage(IMarkdownRenderer renderer, DfmFencesBlockToken token)
 => GenerateReferenceNotFoundErrorMessage(renderer, (DfmFencesToken)token);
Example #26
0
 public static string GetRenderedFencesBlockString(DfmFencesBlockToken token, Options options,
     string errorMessage, string[] codeLines = null)
     => GetRenderedFencesBlockString((DfmFencesToken)token, options, errorMessage, codeLines);
 public abstract bool ValidateAndPrepare(string[] lines, DfmFencesBlockToken token);
Example #28
0
 public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context)
 {
     return(Insert(token, ExposeTokenNameInDfm(token)));
 }