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)); } }
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)); } }
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)); }
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)); }
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)); } }
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); }
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); } }
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 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); }
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)); }
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)); }
public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context) { return Render(renderer, token, (IMarkdownContext)context); }
private static string GetCodeLanguageOrExtension(DfmFencesBlockToken token) { return !string.IsNullOrEmpty(token.Lang) ? token.Lang : Path.GetExtension(token.Path); }
public static string GenerateReferenceNotFoundErrorMessage(IMarkdownRenderer renderer, DfmFencesBlockToken token) => GenerateReferenceNotFoundErrorMessage(renderer, (DfmFencesToken)token);
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)); }
private static string GetCodeLanguageOrExtension(DfmFencesBlockToken token) { return(!string.IsNullOrEmpty(token.Lang) ? token.Lang : Path.GetExtension(token.Path)); }
public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context) { return(Render(renderer, token, (IMarkdownContext)context)); }
public override bool ValidateAndPrepare(string[] lines, DfmFencesBlockToken token) { return(true); }
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); }
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); } }
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);
public virtual StringBuffer Render(IMarkdownRenderer renderer, DfmFencesBlockToken token, MarkdownBlockContext context) { return(Insert(token, ExposeTokenNameInDfm(token))); }