From d49dce8e7092ee0f21d1214a81c4aff103fb7446 Mon Sep 17 00:00:00 2001 From: Millicent Achieng Date: Tue, 5 Mar 2024 09:44:01 +0300 Subject: [PATCH] Preprocess include link that's not the only item on a line (#264) --- ApiDoctor.Validation/Tags/TagProcessor.cs | 28 +++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/ApiDoctor.Validation/Tags/TagProcessor.cs b/ApiDoctor.Validation/Tags/TagProcessor.cs index 39da3dc5..0f5e93a7 100644 --- a/ApiDoctor.Validation/Tags/TagProcessor.cs +++ b/ApiDoctor.Validation/Tags/TagProcessor.cs @@ -23,14 +23,12 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +using ApiDoctor.Validation.Error; +using MarkdownDeep; using System; using System.IO; using System.Linq; -using System.Threading.Tasks; -using ApiDoctor.Validation.Error; using System.Text.RegularExpressions; -using MarkdownDeep; -using System.Collections.Generic; namespace ApiDoctor.Validation.Tags { @@ -49,6 +47,7 @@ public class TagProcessor private static Regex VideoFormat = new Regex(@"\[!VIDEO ((https]?):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?\]", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static Regex CodeSnippetFormat = new Regex(@"\[!(code)(-)(\w*)\[(\w*)\]\((.*\))\]", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static Regex TabHeaderFormat = new Regex(@"#\s\[[#-/.\w]+\]\(#tab\/([-/.\w]+)\)", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static Regex MarkdownLintFormat = new Regex(@"", RegexOptions.Compiled | RegexOptions.IgnoreCase); private Action LogMessage = null; @@ -167,16 +166,17 @@ public string Preprocess(FileInfo sourceFile, IssueLogger issues) if (IsIncludeLine(nextLine)) { // if contains tilde, then file is not in current docset and cannot be validated - if (nextLine.Contains("~")) + if (nextLine.Contains('~')) { LogMessage(new ValidationError(ValidationErrorCode.MarkdownParserError, nextLine, "Cannot validate INCLUDE links referencing content outside of doc set")); continue; } - - var includeFile = GetIncludeFile(nextLine, sourceFile); + var match = IncludeFormat.Match(nextLine); + string includePath = match.Value; + var includeFile = GetIncludeFile(includePath, sourceFile); if (!includeFile.Exists) { - LogMessage(new ValidationError(ValidationErrorCode.ErrorOpeningFile, nextLine, "The included file {0} was not found", includeFile.FullName)); + LogMessage(new ValidationError(ValidationErrorCode.ErrorOpeningFile, includePath, "The included file {0} was not found", includeFile.FullName)); continue; } @@ -184,14 +184,18 @@ public string Preprocess(FileInfo sourceFile, IssueLogger issues) { if (includeFile.FullName.Equals(sourceFile.FullName)) { - LogMessage(new ValidationError(ValidationErrorCode.MarkdownParserError, nextLine, "A Markdown file cannot include itself")); + LogMessage(new ValidationError(ValidationErrorCode.MarkdownParserError, includePath, "A Markdown file cannot include itself")); continue; } // Include Files can have Yaml Front Matter as well. var includeContent = Preprocess(includeFile, issues); var (_, processedContent) = DocFile.ParseAndRemoveYamlFrontMatter(includeContent, issues,true); - writer.WriteLine(processedContent); + + // removing Markdown lint and new lines from the beginning of markdown content since it breaks table structure if include link is within table + processedContent = MarkdownLintFormat.Replace(processedContent, "").TrimStart(Environment.NewLine.ToCharArray()); + + writer.WriteLine(nextLine.Replace(includePath, processedContent)); } else { @@ -340,9 +344,9 @@ private bool IsEndLine(string text) return text.Trim().ToUpper().Equals("[END]"); } - private bool IsIncludeLine(string text) + private static bool IsIncludeLine(string text) { - if (text.ToUpper().Contains("INCLUDE")) + if (text.Contains("INCLUDE", StringComparison.OrdinalIgnoreCase)) { return IncludeFormat.IsMatch(text); }