From 7ef619223e4f534ec844b04e52bfc01c11e9ed6f Mon Sep 17 00:00:00 2001 From: Yufei Huang Date: Mon, 17 Jul 2023 10:55:19 +0800 Subject: [PATCH] chore: drop support for md.style --- .../BuildConceptualDocument.cs | 2 +- src/Docfx.Build.Engine/HostService.cs | 19 +- .../Processors/MarkdownInterpreter.cs | 2 +- .../MarkdigMarkdownService.cs | 19 +- .../Validation/MarkdownValidatorBuilder.cs | 219 ---------------- src/Docfx.MarkdigEngine/Validation/Tag.cs | 101 ------- .../Validation/TagValidator.cs | 77 ------ .../Validation/ValidationExtension.cs | 54 ---- src/Docfx.Plugins/IHostService.cs | 1 - src/Docfx.Plugins/MarkdownStyleConfig.cs | 20 -- src/Docfx.Plugins/MarkdownSytleDefinition.cs | 19 -- .../MarkdownTagValidationRule.cs | 48 ---- src/Docfx.Plugins/MarkdownValidationRule.cs | 40 --- .../MarkdownValidationSetting.cs | 33 --- .../DocumentBuilderTest.cs | 172 ------------ .../ValidationTest.cs | 246 ------------------ 16 files changed, 11 insertions(+), 1061 deletions(-) delete mode 100644 src/Docfx.MarkdigEngine/Validation/MarkdownValidatorBuilder.cs delete mode 100644 src/Docfx.MarkdigEngine/Validation/Tag.cs delete mode 100644 src/Docfx.MarkdigEngine/Validation/TagValidator.cs delete mode 100644 src/Docfx.MarkdigEngine/Validation/ValidationExtension.cs delete mode 100644 src/Docfx.Plugins/MarkdownStyleConfig.cs delete mode 100644 src/Docfx.Plugins/MarkdownSytleDefinition.cs delete mode 100644 src/Docfx.Plugins/MarkdownTagValidationRule.cs delete mode 100644 src/Docfx.Plugins/MarkdownValidationRule.cs delete mode 100644 src/Docfx.Plugins/MarkdownValidationSetting.cs delete mode 100644 test/Docfx.MarkdigEngine.Tests/ValidationTest.cs diff --git a/src/Docfx.Build.ConceptualDocuments/BuildConceptualDocument.cs b/src/Docfx.Build.ConceptualDocuments/BuildConceptualDocument.cs index 641240e23a5..1cc73e0dcf9 100644 --- a/src/Docfx.Build.ConceptualDocuments/BuildConceptualDocument.cs +++ b/src/Docfx.Build.ConceptualDocuments/BuildConceptualDocument.cs @@ -29,7 +29,7 @@ public override void Build(FileModel model, IHostService host) } var content = (Dictionary)model.Content; var markdown = (string)content[ConceptualKey]; - var result = host.Markup(markdown, model.OriginalFileAndType, false, true); + var result = host.Markup(markdown, model.OriginalFileAndType, false); var htmlInfo = HtmlDocumentUtility.SeparateHtml(result.Html); content["rawTitle"] = htmlInfo.RawTitle; diff --git a/src/Docfx.Build.Engine/HostService.cs b/src/Docfx.Build.Engine/HostService.cs index 39bc5bfc2f4..ff9f6aa1248 100644 --- a/src/Docfx.Build.Engine/HostService.cs +++ b/src/Docfx.Build.Engine/HostService.cs @@ -104,20 +104,7 @@ public MarkupResult Markup(string markdown, FileAndType ft) public MarkupResult Markup(string markdown, FileAndType ft, bool omitParse) { - return Markup(markdown, ft, omitParse, false); - } - - public MarkupResult Markup(string markdown, FileAndType ft, bool omitParse, bool enableValidation) - { - if (markdown == null) - { - throw new ArgumentNullException(nameof(markdown)); - } - if (ft == null) - { - throw new ArgumentNullException(nameof(ft)); - } - return MarkupCore(markdown, ft, omitParse, enableValidation); + return MarkupCore(markdown, ft, omitParse); } public MarkupResult Parse(MarkupResult markupResult, FileAndType ft) @@ -125,12 +112,12 @@ public MarkupResult Parse(MarkupResult markupResult, FileAndType ft) return MarkupUtility.Parse(markupResult, ft.File, SourceFiles); } - private MarkupResult MarkupCore(string markdown, FileAndType ft, bool omitParse, bool enableValidation) + private MarkupResult MarkupCore(string markdown, FileAndType ft, bool omitParse) { try { var mr = MarkdownService is MarkdigMarkdownService markdig - ? markdig.Markup(markdown, ft.File, enableValidation, ft.Type is DocumentType.Overwrite) + ? markdig.Markup(markdown, ft.File, ft.Type is DocumentType.Overwrite) : MarkdownService.Markup(markdown, ft.File); if (omitParse) { diff --git a/src/Docfx.Build.SchemaDriven/Processors/MarkdownInterpreter.cs b/src/Docfx.Build.SchemaDriven/Processors/MarkdownInterpreter.cs index 232a0b62db2..2e0fc9cb969 100644 --- a/src/Docfx.Build.SchemaDriven/Processors/MarkdownInterpreter.cs +++ b/src/Docfx.Build.SchemaDriven/Processors/MarkdownInterpreter.cs @@ -31,7 +31,7 @@ private static string MarkupCore(string content, IProcessContext context, string { var host = context.Host; - var mr = host.Markup(content, context.GetOriginalContentFile(path), false, true); + var mr = host.Markup(content, context.GetOriginalContentFile(path), false); (context.FileLinkSources).Merge(mr.FileLinkSources); (context.UidLinkSources).Merge(mr.UidLinkSources); (context.Dependency).UnionWith(mr.Dependency); diff --git a/src/Docfx.MarkdigEngine/MarkdigMarkdownService.cs b/src/Docfx.MarkdigEngine/MarkdigMarkdownService.cs index 5464797b52d..704a03d34c2 100644 --- a/src/Docfx.MarkdigEngine/MarkdigMarkdownService.cs +++ b/src/Docfx.MarkdigEngine/MarkdigMarkdownService.cs @@ -16,7 +16,6 @@ public class MarkdigMarkdownService : IMarkdownService public string Name => "markdig"; private readonly MarkdownServiceParameters _parameters; - private readonly MarkdownValidatorBuilder _mvb; private readonly MarkdownContext _context; private readonly Func _configureMarkdig; @@ -26,7 +25,6 @@ public MarkdigMarkdownService( { _parameters = parameters; _configureMarkdig = configureMarkdig; - _mvb = MarkdownValidatorBuilder.Create(parameters); _context = new MarkdownContext( key => _parameters.Tokens.TryGetValue(key, out var value) ? value : null, (code, message, origin, line) => Logger.LogInfo(message, null, InclusionContext.File.ToString(), line?.ToString(), code), @@ -40,10 +38,10 @@ public MarkdigMarkdownService( public MarkupResult Markup(string content, string filePath) { - return Markup(content, filePath, false, false); + return Markup(content, filePath, false); } - public MarkupResult Markup(string content, string filePath, bool enableValidation, bool multipleYamlHeader) + public MarkupResult Markup(string content, string filePath, bool multipleYamlHeader) { if (content == null) { @@ -55,7 +53,7 @@ public MarkupResult Markup(string content, string filePath, bool enableValidatio throw new ArgumentException("file path can't be null or empty."); } - var pipeline = CreateMarkdownPipeline(isInline: false, enableValidation, multipleYamlHeader); + var pipeline = CreateMarkdownPipeline(isInline: false, multipleYamlHeader); using (InclusionContext.PushFile((RelativePath)filePath)) { @@ -84,7 +82,7 @@ public MarkdownDocument Parse(string content, string filePath, bool isInline) throw new ArgumentException("file path can't be null or empty."); } - var pipeline = CreateMarkdownPipeline(isInline, enableValidation: false); + var pipeline = CreateMarkdownPipeline(isInline); using (InclusionContext.PushFile((RelativePath)filePath)) { @@ -112,7 +110,7 @@ public MarkupResult Render(MarkdownDocument document, bool isInline) throw new ArgumentNullException("file path can't be found in AST."); } - var pipeline = CreateMarkdownPipeline(isInline, enableValidation: false); + var pipeline = CreateMarkdownPipeline(isInline); using (InclusionContext.PushFile((RelativePath)filePath)) { @@ -130,7 +128,7 @@ public MarkupResult Render(MarkdownDocument document, bool isInline) } } - private MarkdownPipeline CreateMarkdownPipeline(bool isInline, bool enableValidation, bool multipleYamlHeader = false) + private MarkdownPipeline CreateMarkdownPipeline(bool isInline, bool multipleYamlHeader = false) { var enableSourceInfo = _parameters?.Extensions?.EnableSourceInfo ?? true; @@ -144,11 +142,6 @@ private MarkdownPipeline CreateMarkdownPipeline(bool isInline, bool enableValida builder.UseLineNumber(file => ((RelativePath)file).RemoveWorkingFolder()); } - if (enableValidation) - { - builder.Extensions.Add(new ValidationExtension(_mvb, _context)); - } - if (isInline) { builder.UseInlineOnly(); diff --git a/src/Docfx.MarkdigEngine/Validation/MarkdownValidatorBuilder.cs b/src/Docfx.MarkdigEngine/Validation/MarkdownValidatorBuilder.cs deleted file mode 100644 index a3dc73ed9b4..00000000000 --- a/src/Docfx.MarkdigEngine/Validation/MarkdownValidatorBuilder.cs +++ /dev/null @@ -1,219 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; - -using Docfx.Common; -using Docfx.Plugins; - -namespace Docfx.MarkdigEngine.Extensions; - -public class MarkdownValidatorBuilder -{ - private readonly List> _validators = new(); - private readonly List> _tagValidators = new(); - private readonly Dictionary _globalValidators = new(); - private readonly List _settings = new(); - - public const string DefaultValidatorName = "default"; - public const string MarkdownValidatePhaseName = "Markdown style"; - - public static MarkdownValidatorBuilder Create(MarkdownServiceParameters parameters) - { - var builder = new MarkdownValidatorBuilder(); - if (parameters != null) - { - LoadValidatorConfig(parameters.BasePath, parameters.TemplateDir, builder); - } - - return builder; - } - - public IMarkdownObjectRewriter CreateRewriter(MarkdownContext context) - { - return new TagValidator(GetEnabledTagRules().ToImmutableList(), context); - } - - public void AddValidators(MarkdownValidationRule[] rules) - { - if (rules == null) - { - return; - } - foreach (var rule in rules) - { - if (string.IsNullOrEmpty(rule.ContractName)) - { - continue; - } - _globalValidators[rule.ContractName] = rule; - } - } - - public void AddValidators(string category, Dictionary validators) - { - if (validators == null) - { - return; - } - foreach (var pair in validators) - { - if (string.IsNullOrEmpty(pair.Value.ContractName)) - { - continue; - } - _validators.Add(new RuleWithId - { - Category = category, - Id = pair.Key, - Rule = pair.Value, - }); - } - } - - public void AddTagValidators(MarkdownTagValidationRule[] validators) - { - if (validators == null) - { - return; - } - - foreach (var item in validators) - { - _tagValidators.Add(new RuleWithId - { - Category = null, - Id = null, - Rule = item - }); - } - } - - internal void AddTagValidators(string category, Dictionary validators) - { - if (validators == null) - { - return; - } - - foreach (var pair in validators) - { - _tagValidators.Add(new RuleWithId - { - Category = category, - Id = pair.Key, - Rule = pair.Value, - }); - } - } - - internal void AddSettings(MarkdownValidationSetting[] settings) - { - if (settings == null) - { - return; - } - foreach (var setting in settings) - { - _settings.Add(setting); - } - } - - private void EnsureDefaultValidator() - { - if (!_globalValidators.ContainsKey(DefaultValidatorName)) - { - _globalValidators[DefaultValidatorName] = new MarkdownValidationRule - { - ContractName = DefaultValidatorName - }; - } - } - - private static void LoadValidatorConfig(string baseDir, string templateDir, MarkdownValidatorBuilder builder) - { - if (string.IsNullOrEmpty(baseDir)) - { - return; - } - - if (templateDir != null) - { - var configFolder = Path.Combine(templateDir, MarkdownStyleDefinition.MarkdownStyleDefinitionFolderName); - if (Directory.Exists(configFolder)) - { - LoadValidatorDefinition(configFolder, builder); - } - } - - var configFile = Path.Combine(baseDir, MarkdownStyleConfig.MarkdownStyleFileName); - if (EnvironmentContext.FileAbstractLayer.Exists(configFile)) - { - var config = JsonUtility.Deserialize(configFile); - builder.AddValidators(config.Rules); - builder.AddTagValidators(config.TagRules); - builder.AddSettings(config.Settings); - } - builder.EnsureDefaultValidator(); - } - - private static void LoadValidatorDefinition(string mdStyleDefPath, MarkdownValidatorBuilder builder) - { - if (Directory.Exists(mdStyleDefPath)) - { - foreach (var configFile in Directory.GetFiles(mdStyleDefPath, "*" + MarkdownStyleDefinition.MarkdownStyleDefinitionFilePostfix)) - { - var fileName = Path.GetFileName(configFile); - var category = fileName.Remove(fileName.Length - MarkdownStyleDefinition.MarkdownStyleDefinitionFilePostfix.Length); - var config = JsonUtility.Deserialize(configFile); - builder.AddTagValidators(category, config.TagRules); - builder.AddValidators(category, config.Rules); - } - } - } - - private IEnumerable GetEnabledTagRules() - { - foreach (var item in _tagValidators) - { - if (IsDisabledBySetting(item) ?? item.Rule.Disable) - { - continue; - } - yield return item.Rule; - } - } - - private bool? IsDisabledBySetting(RuleWithId item) - { - bool? categoryDisable = null; - bool? idDisable = null; - if (item.Category != null) - { - foreach (var setting in _settings) - { - if (setting.Category == item.Category) - { - if (setting.Id == null) - { - categoryDisable = setting.Disable; - } - else if (setting.Id == item.Id) - { - idDisable = setting.Disable; - } - } - } - } - return idDisable ?? categoryDisable; - } - - #region Nested Classes - private sealed class RuleWithId - { - public T Rule { get; set; } - public string Category { get; set; } - public string Id { get; set; } - } - #endregion -} diff --git a/src/Docfx.MarkdigEngine/Validation/Tag.cs b/src/Docfx.MarkdigEngine/Validation/Tag.cs deleted file mode 100644 index 98848aaf0fa..00000000000 --- a/src/Docfx.MarkdigEngine/Validation/Tag.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Text.RegularExpressions; - -using Markdig.Helpers; -using Markdig.Syntax; -using Markdig.Syntax.Inlines; - -namespace Docfx.MarkdigEngine.Extensions; - -internal class Tag -{ - private static readonly Regex OpeningTag = new(@"\<(\w+)((?:""[^""]*""|'[^']*'|[^'"">])*?)\>", RegexOptions.Compiled); - private static readonly Regex ClosingTag = new(@"\])*?)\>", RegexOptions.Compiled); - - public int Line { get; set; } - - public string Name { get; set; } - - public string Content { get; set; } - - public bool IsOpening { get; set; } - - public static IEnumerable Convert(IMarkdownObject markdownObject) - { - if (markdownObject is HtmlBlock block) - { - return Convert(block); - } - - if (markdownObject is HtmlInline inline) - { - return Convert(inline); - } - - return null; - } - - private static IEnumerable Convert(HtmlBlock block) - { - var lines = block.Lines; - for (var i = 0; i < lines.Count; i++) - { - var line = lines.Lines[i]; - foreach (var tag in Convert(line) ?? Enumerable.Empty()) - { - yield return tag; - } - } - } - - private static IEnumerable Convert(StringLine line) - { - var matches = OpeningTag.Matches(line.ToString()); - var isOpening = true; - foreach (Match m in matches) - { - yield return new Tag - { - Line = line.Line, - Content = line.ToString(), - Name = m.Groups[1].Value, - IsOpening = isOpening - }; - } - - matches = ClosingTag.Matches(line.ToString()); - isOpening = false; - foreach (Match m in matches) - { - yield return new Tag - { - Line = line.Line, - Content = line.ToString(), - Name = m.Groups[1].Value, - IsOpening = isOpening - }; - } - } - - private static IEnumerable Convert(HtmlInline inline) - { - var text = inline.Tag; - var match = OpeningTag.Match(text); - var isOpening = true; - if (match.Length < 1) - { - match = ClosingTag.Match(text); - isOpening = false; - } - - yield return new Tag - { - Name = match.Groups[1].Value, - Content = inline.Tag, - IsOpening = isOpening, - Line = inline.Line - }; - } -} diff --git a/src/Docfx.MarkdigEngine/Validation/TagValidator.cs b/src/Docfx.MarkdigEngine/Validation/TagValidator.cs deleted file mode 100644 index bd830c902ea..00000000000 --- a/src/Docfx.MarkdigEngine/Validation/TagValidator.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Immutable; - -using Markdig.Syntax; -using Docfx.Plugins; - -namespace Docfx.MarkdigEngine.Extensions; - -internal class TagValidator : IMarkdownObjectRewriter -{ - public ImmutableList Validators { get; } - - private readonly MarkdownContext _context; - - public TagValidator(ImmutableList validators, MarkdownContext context) - { - _context = context; - Validators = validators; - } - - public void Validate(IMarkdownObject markdownObject) - { - var tags = Tag.Convert(markdownObject); - if (tags == null) - { - return; - } - - foreach (var tag in tags) - { - foreach (var validator in Validators) - { - ValidateOne(tag, validator); - } - } - } - - private void ValidateOne(Tag tag, MarkdownTagValidationRule validator) - { - if (tag.IsOpening || !validator.OpeningTagOnly) - { - var hasTagName = validator.TagNames.Any(tagName => string.Equals(tagName, tag.Name, StringComparison.OrdinalIgnoreCase)); - if (hasTagName ^ (validator.Relation == TagRelation.NotIn)) - { - ValidateCore(tag, validator); - } - } - } - - private void ValidateCore(Tag tag, MarkdownTagValidationRule validator) - { - switch (validator.Behavior) - { - case TagValidationBehavior.Warning: - _context.LogWarning("invalid-markdown-tag", string.Format(validator.MessageFormatter, tag.Name, tag.Content), null, line: tag.Line); - return; - case TagValidationBehavior.Error: - _context.LogError("invalid-markdown-tag", string.Format(validator.MessageFormatter, tag.Name, tag.Content), null, line: tag.Line); - return; - case TagValidationBehavior.None: - default: - return; - } - } - - void IMarkdownObjectRewriter.PreProcess(IMarkdownObject markdownObject) { } - - void IMarkdownObjectRewriter.PostProcess(IMarkdownObject markdownObject) { } - - IMarkdownObject IMarkdownObjectRewriter.Rewrite(IMarkdownObject markdownObject) - { - Validate(markdownObject); - return markdownObject; - } -} diff --git a/src/Docfx.MarkdigEngine/Validation/ValidationExtension.cs b/src/Docfx.MarkdigEngine/Validation/ValidationExtension.cs deleted file mode 100644 index 3dc5909ec4e..00000000000 --- a/src/Docfx.MarkdigEngine/Validation/ValidationExtension.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Markdig; -using Markdig.Renderers; -using Markdig.Syntax; -using Docfx.Common; - -namespace Docfx.MarkdigEngine.Extensions; - -public class ValidationExtension : IMarkdownExtension -{ - private readonly MarkdownValidatorBuilder _mvb; - - private readonly MarkdownContext _context; - - public ValidationExtension(MarkdownValidatorBuilder validationBuilder, MarkdownContext context) - { - _mvb = validationBuilder; - _context = context; - } - - public void Setup(MarkdownPipelineBuilder pipeline) - { - var tokenRewriter = _mvb.CreateRewriter(_context); - var visitor = new MarkdownDocumentVisitor(tokenRewriter); - - pipeline.DocumentProcessed += document => - { - SetSchemaName(document); - visitor.Visit(document); - }; - } - - public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) - { - - } - - public static void SetSchemaName(MarkdownDocument document) - { - // TODO: add this detection logic in terms of performance optimization, should remove once mime is available in context - if (InclusionContext.IsInclude - && (string.Equals(Path.GetExtension(InclusionContext.RootFile?.ToString()), ".yml", StringComparison.OrdinalIgnoreCase) - || string.Equals(Path.GetExtension(InclusionContext.RootFile?.ToString()), ".yaml", StringComparison.OrdinalIgnoreCase))) - { - var schemaName = YamlMime.ReadMime(InclusionContext.RootFile?.ToString()); - if (!string.IsNullOrEmpty(schemaName)) - { - document.SetData("SchemaName", schemaName); - } - } - } -} diff --git a/src/Docfx.Plugins/IHostService.cs b/src/Docfx.Plugins/IHostService.cs index 22a550f8240..f4e96ef49ff 100644 --- a/src/Docfx.Plugins/IHostService.cs +++ b/src/Docfx.Plugins/IHostService.cs @@ -26,7 +26,6 @@ public interface IHostService MarkupResult Parse(MarkupResult markupResult, FileAndType ft); MarkupResult Markup(string markdown, FileAndType ft); MarkupResult Markup(string markdown, FileAndType ft, bool omitParse); - MarkupResult Markup(string markdown, FileAndType ft, bool omitParse, bool enableValidation); ImmutableDictionary SourceFiles { get; } ImmutableHashSet GetAllUids(); ImmutableList GetModels(DocumentType? type = null); diff --git a/src/Docfx.Plugins/MarkdownStyleConfig.cs b/src/Docfx.Plugins/MarkdownStyleConfig.cs deleted file mode 100644 index 5bd5d1c008c..00000000000 --- a/src/Docfx.Plugins/MarkdownStyleConfig.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Newtonsoft.Json; - -namespace Docfx.Plugins; - -public class MarkdownStyleConfig -{ - public const string MarkdownStyleFileName = "md.style"; - - [JsonProperty("metadataRules")] - public MarkdownMetadataValidationRule[] MetadataRules { get; set; } - [JsonProperty("rules")] - public MarkdownValidationRule[] Rules { get; set; } - [JsonProperty("tagRules")] - public MarkdownTagValidationRule[] TagRules { get; set; } - [JsonProperty("settings")] - public MarkdownValidationSetting[] Settings { get; set; } -} diff --git a/src/Docfx.Plugins/MarkdownSytleDefinition.cs b/src/Docfx.Plugins/MarkdownSytleDefinition.cs deleted file mode 100644 index efa298fb08b..00000000000 --- a/src/Docfx.Plugins/MarkdownSytleDefinition.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Newtonsoft.Json; - -namespace Docfx.Plugins; - -public class MarkdownStyleDefinition -{ - public const string MarkdownStyleDefinitionFilePostfix = ".md.style"; - public const string MarkdownStyleDefinitionFolderName = "md.styles"; - - [JsonProperty("metadataRules")] - public Dictionary MetadataRules { get; set; } - [JsonProperty("rules")] - public Dictionary Rules { get; set; } - [JsonProperty("tagRules")] - public Dictionary TagRules { get; set; } -} diff --git a/src/Docfx.Plugins/MarkdownTagValidationRule.cs b/src/Docfx.Plugins/MarkdownTagValidationRule.cs deleted file mode 100644 index 200270f5e4e..00000000000 --- a/src/Docfx.Plugins/MarkdownTagValidationRule.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; - -using Newtonsoft.Json; - -namespace Docfx.Plugins; - -public class MarkdownTagValidationRule -{ - /// - /// The names of tag. - /// - [JsonProperty("tagNames", Required = Required.Always)] - public List TagNames { get; set; } - - /// - /// The relation for tags. - /// - [JsonProperty("relation")] - public TagRelation Relation { get; set; } - - /// - /// Define tag's behavior. - /// - [JsonProperty("behavior", Required = Required.Always)] - public TagValidationBehavior Behavior { get; set; } - - /// - /// The message formatter for warning and error. '{0}' is name of tag, '{1}' is the full tag. - /// - [JsonProperty("messageFormatter", Required = Required.Always)] - public string MessageFormatter { get; set; } - - /// - /// Only validate opening tag. - /// - [JsonProperty("openingTagOnly")] - public bool OpeningTagOnly { get; set; } - - /// - /// Whether to disable this rule by default. - /// - [DefaultValue(false)] - [JsonProperty("disable")] - public bool Disable { get; set; } -} diff --git a/src/Docfx.Plugins/MarkdownValidationRule.cs b/src/Docfx.Plugins/MarkdownValidationRule.cs deleted file mode 100644 index a731639e3d1..00000000000 --- a/src/Docfx.Plugins/MarkdownValidationRule.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; - -using Newtonsoft.Json; - -namespace Docfx.Plugins; - -public class MarkdownValidationRule -{ - /// - /// The contract name of rule. - /// - [Obsolete("Please use ContractName.")] - [JsonProperty("name")] - public string RuleName - { - get { return ContractName; } - set { ContractName = value; } - } - - /// - /// The contract name of rule. - /// - [JsonProperty("contractName")] - public string ContractName { get; set; } - - /// - /// Whether to disable this rule by default. - /// - [DefaultValue(false)] - [JsonProperty("disable")] - public bool Disable { get; set; } - - public static explicit operator MarkdownValidationRule(string contractName) - { - return new MarkdownValidationRule { ContractName = contractName }; - } -} diff --git a/src/Docfx.Plugins/MarkdownValidationSetting.cs b/src/Docfx.Plugins/MarkdownValidationSetting.cs deleted file mode 100644 index edf3e3a47d5..00000000000 --- a/src/Docfx.Plugins/MarkdownValidationSetting.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.ComponentModel; - -using Newtonsoft.Json; - -namespace Docfx.Plugins; - -public class MarkdownValidationSetting -{ - /// - /// The category of rule - /// - [JsonProperty("category", Required = Required.Always)] - public string Category { get; set; } - /// - /// The id of rule. - /// - [JsonProperty("id")] - public string Id { get; set; } - /// - /// Whether to disable this rule by default. - /// - [DefaultValue(false)] - [JsonProperty("disable")] - public bool Disable { get; set; } - - public static explicit operator MarkdownValidationSetting(string category) - { - return new MarkdownValidationSetting { Category = category }; - } -} diff --git a/test/Docfx.Build.Engine.Tests/DocumentBuilderTest.cs b/test/Docfx.Build.Engine.Tests/DocumentBuilderTest.cs index 09446e59ecc..2a3dc98e742 100644 --- a/test/Docfx.Build.Engine.Tests/DocumentBuilderTest.cs +++ b/test/Docfx.Build.Engine.Tests/DocumentBuilderTest.cs @@ -143,20 +143,6 @@ public void TestBuild() "Test xrefmap with duplicate uid in different files: XRef2 should be recorded with file test/test.md" }, _inputFolder); - File.WriteAllText(MarkdownStyleConfig.MarkdownStyleFileName, @"{ -rules : [ - ""foo"", - { name: ""bar"", disable: true} -], -tagRules : [ - { - tagNames: [""p""], - behavior: ""Warning"", - messageFormatter: ""Tag {0} is not valid."", - openingTagOnly: true - } -] -}"); FileCollection files = new(Directory.GetCurrentDirectory()); files.Add(DocumentType.Article, new[] { tocFile, conceptualFile, conceptualFile2, conceptualFile3, conceptualFile4 }); @@ -184,17 +170,6 @@ public void TestBuild() } - { - // check log for markdown stylecop. - Assert.Equal(2, Listener.Items.Count); - - Assert.Equal("Tag p is not valid.", Listener.Items[0].Message); - Assert.Equal(LogLevel.Warning, Listener.Items[0].LogLevel); - - Assert.Equal("Tag p is not valid.", Listener.Items[1].Message); - Assert.Equal(LogLevel.Warning, Listener.Items[1].LogLevel); - } - { // check toc. Assert.True(File.Exists(Path.Combine(_outputFolder, Path.ChangeExtension(tocFile, RawModelFileExtension)))); @@ -334,153 +309,6 @@ public void TestBuild() } } - [Fact] - public void TestMarkdownStyleInPlugins() - { - #region Prepare test data - var resourceFile = Path.GetFileName(typeof(DocumentBuilderTest).Assembly.Location); - var resourceMetaFile = resourceFile + ".meta"; - - CreateFile("conceptual.html.primary.tmpl", "{{{conceptual}}}", _templateFolder); - - var tocFile = CreateFile("toc.md", - new[] - { - "# [test1](test.md)", - "## [test2](test/test.md)", - "# Api", - "## [Console](@System.Console)", - "## [ConsoleColor](xref:System.ConsoleColor)", - }, - _inputFolder); - var conceptualFile = CreateFile("test.md", - new[] - { - "---", - "uid: XRef1", - "a: b", - "b:", - " c: e", - "---", - "# Hello World", - "Test XRef: @XRef1", - "Test link: [link text](test/test.md)", - "Test link: [link text 2](../" + resourceFile + ")", - "Test link style xref: [link text 3](xref:XRef2 \"title\")", - "Test link style xref with anchor: [link text 4](xref:XRef2#anchor \"title\")", - "Test encoded link style xref with anchor: [link text 5](xref:%58%52%65%66%32#anchor \"title\")", - "Test invalid link style xref with anchor: [link text 6](xref:invalid#anchor \"title\")", - "Test autolink style xref: ", - "Test autolink style xref with anchor: ", - "Test encoded autolink style xref with anchor: ", - "Test invalid autolink style xref with anchor: ", - "Test short xref: @XRef2", - "

", - "test", - }, - _inputFolder); - var conceptualFile2 = CreateFile("test/test.md", - new[] - { - "---", - "uid: XRef2", - "a: b", - "b:", - " c: e", - "---", - "# Hello World", - "Test XRef: @XRef2", - "Test link: [link text](../test.md)", - "

", - "test", - }, - _inputFolder); - - File.WriteAllText(resourceMetaFile, @"{ abc: ""xyz"", uid: ""r1"" }"); - File.WriteAllText(MarkdownStyleConfig.MarkdownStyleFileName, @"{ -settings : [ - { category: ""div"", disable: true}, - { category: ""p"", id: ""p-3"", disable: true} -], -}"); - CreateFile( - MarkdownStyleDefinition.MarkdownStyleDefinitionFolderName + "/p" + MarkdownStyleDefinition.MarkdownStyleDefinitionFilePostfix, - @"{ - tagRules : { - ""p-1"": { - tagNames: [""p""], - behavior: ""Warning"", - messageFormatter: ""Tag {0} is not valid."", - openingTagOnly: true - }, - ""p-2"": { - tagNames: [""p""], - behavior: ""Warning"", - messageFormatter: ""Tag {0} is not valid."", - openingTagOnly: false, - disable: true - }, - ""p-3"": { - tagNames: [""p""], - behavior: ""Warning"", - messageFormatter: ""Tag {0} is not valid."", - openingTagOnly: false, - } - } -} -", _templateFolder); - CreateFile( - MarkdownStyleDefinition.MarkdownStyleDefinitionFolderName + "/div" + MarkdownStyleDefinition.MarkdownStyleDefinitionFilePostfix, - @"{ - tagRules : { - ""div-1"": { - tagNames: [""div""], - behavior: ""Warning"", - messageFormatter: ""Tag {0} is not valid."", - openingTagOnly: true - } - } -} -", _templateFolder); - - FileCollection files = new(Directory.GetCurrentDirectory()); - files.Add(DocumentType.Article, new[] { tocFile, conceptualFile, conceptualFile2 }); - files.Add(DocumentType.Article, new[] { "TestData/System.Console.csyml", "TestData/System.ConsoleColor.csyml" }, "TestData/", null); - files.Add(DocumentType.Resource, new[] { resourceFile }); - #endregion - - Init("Markdown style"); - try - { - using (new LoggerPhaseScope(nameof(DocumentBuilderTest))) - { - BuildDocument( - files, - new Dictionary - { - ["meta"] = "Hello world!", - }, - templateFolder: _templateFolder); - } - - { - // check log for markdown stylecop. - Assert.Equal(2, Listener.Items.Count); - - Assert.Equal("Tag p is not valid.", Listener.Items[0].Message); - Assert.Equal(LogLevel.Warning, Listener.Items[0].LogLevel); - - Assert.Equal("Tag p is not valid.", Listener.Items[1].Message); - Assert.Equal(LogLevel.Warning, Listener.Items[1].LogLevel); - } - } - finally - { - CleanUp(); - File.Delete(resourceMetaFile); - } - } - [Fact] public void TestBuildConceptualWithTemplateShouldSucceed() { diff --git a/test/Docfx.MarkdigEngine.Tests/ValidationTest.cs b/test/Docfx.MarkdigEngine.Tests/ValidationTest.cs deleted file mode 100644 index c58e9dbb5fa..00000000000 --- a/test/Docfx.MarkdigEngine.Tests/ValidationTest.cs +++ /dev/null @@ -1,246 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Markdig; -using Docfx.Common; -using Docfx.MarkdigEngine.Extensions; -using Docfx.Plugins; -using Xunit; - -namespace Docfx.MarkdigEngine.Tests; - -public class ValidationTest -{ - public const string MarkdownValidatePhaseName = "Markdown style"; - - private readonly MarkdownContext DefaultContext = - new( - null, - (code, message, origin, line) => Logger.LogInfo(message, null, null, line.ToString(), code), - (code, message, origin, line) => Logger.LogSuggestion(message, null, null, line.ToString(), code), - (code, message, origin, line) => Logger.LogWarning(message, null, null, line.ToString(), code), - (code, message, origin, line) => Logger.LogError(message, null, null, line.ToString(), code)); - - [Fact] - [Trait("Related", "Validation")] - public void TestHtmlBlockTagValidation() - { - var content = @" -
- x - y -

- z -

-            a*b*c
-        
-

-
-"; - - var builder = MarkdownValidatorBuilder.Create(null); - - builder.AddTagValidators(new[] - { - new MarkdownTagValidationRule - { - TagNames = new List { "em", "div" }, - MessageFormatter = "Invalid tag({0})!", - Behavior = TagValidationBehavior.Error, - OpeningTagOnly = true, - }, - new MarkdownTagValidationRule - { - TagNames = new List { "h1" }, - MessageFormatter = "Warning tag({0})!", - Behavior = TagValidationBehavior.Warning, - }, - new MarkdownTagValidationRule - { - TagNames = new List { "script" }, - MessageFormatter = "Warning tag({0})!", - Behavior = TagValidationBehavior.Warning, - OpeningTagOnly = true - }, - new MarkdownTagValidationRule - { - TagNames = new List { "pre" }, - MessageFormatter = "Warning tag({0})!", - Behavior = TagValidationBehavior.Warning, - } - }); - - var listener = TestLoggerListener.CreateLoggerListenerWithPhaseEqualFilter(MarkdownValidatePhaseName); - using (new LoggerPhaseScope(MarkdownValidatePhaseName)) - { - var html = Markup(content, builder.CreateRewriter(DefaultContext), listener); - - Assert.Equal(@"
- x - y -

- z -

-            a*b*c
-        
-

-
- -".Replace("\r\n", "\n"), html); - } - Assert.Equal(new[] - { - "Invalid tag(div)!", - "Invalid tag(EM)!", - "Warning tag(h1)!", - "Warning tag(pre)!", - "Warning tag(pre)!", - "Warning tag(h1)!", - "Warning tag(script)!" - }, from item in listener.Items select item.Message); - } - - [Fact] - [Trait("Related", "Validation")] - public void TestHtmlBlockTagNotInRelationValidation() - { - var content = @" -
- x - y -

- z -

-            a*b*c
-        
-

-
-"; - - var builder = MarkdownValidatorBuilder.Create(null); - builder.AddTagValidators(new[] - { - new MarkdownTagValidationRule - { - TagNames = new List { "h1", "code", "pre", "div" }, - MessageFormatter = "Invalid tag({0})!", - Behavior = TagValidationBehavior.Error, - OpeningTagOnly = true, - Relation = TagRelation.NotIn - } - }); - - var listener = TestLoggerListener.CreateLoggerListenerWithPhaseEqualFilter(MarkdownValidatePhaseName); - using (new LoggerPhaseScope(MarkdownValidatePhaseName)) - { - var html = Markup(content, builder.CreateRewriter(DefaultContext), listener); - - Assert.Equal(@"
- x - y -

- z -

-            a*b*c
-        
-

-
- -".Replace("\r\n", "\n"), html); - } - Assert.Equal(3, listener.Items.Count); - Assert.Equal(new[] - { - "Invalid tag(i)!", - "Invalid tag(EM)!", - "Invalid tag(script)!" - }, from item in listener.Items select item.Message); - } - - [Fact] - [Trait("Related", "Validation")] - public void TestHtmlInlineTagValidation() - { - var content = @"This is inline html:
xy

z
a*b*c

- - end."; - - var builder = MarkdownValidatorBuilder.Create(null); - - builder.AddTagValidators(new[] - { - new MarkdownTagValidationRule - { - TagNames = new List { "em", "div" }, - MessageFormatter = "Invalid tag({0})!", - Behavior = TagValidationBehavior.Error, - OpeningTagOnly = true, - }, - new MarkdownTagValidationRule - { - TagNames = new List { "h1" }, - MessageFormatter = "Warning tag({0})!", - Behavior = TagValidationBehavior.Warning, - }, - new MarkdownTagValidationRule - { - TagNames = new List { "script" }, - MessageFormatter = "Warning tag({0})!", - Behavior = TagValidationBehavior.Warning, - OpeningTagOnly = true - }, - new MarkdownTagValidationRule - { - TagNames = new List { "pre" }, - MessageFormatter = "Warning tag({0})!", - Behavior = TagValidationBehavior.Warning, - }, - }); - - var listener = TestLoggerListener.CreateLoggerListenerWithPhaseEqualFilter(MarkdownValidatePhaseName); - using (new LoggerPhaseScope(MarkdownValidatePhaseName)) - { - var html = Markup(content, builder.CreateRewriter(DefaultContext), listener); - - Assert.Equal(@"

This is inline html:

xy

z
abc

- end. -".Replace("\r\n", "\n"), html); - } - Assert.Equal(7, listener.Items.Count); - Assert.Equal(new[] - { - "Invalid tag(div)!", - "Invalid tag(EM)!", - "Warning tag(h1)!", - "Warning tag(pre)!", - "Warning tag(pre)!", - "Warning tag(h1)!", - "Warning tag(script)!" - }, from item in listener.Items select item.Message); - } - - private string Markup(string content, IMarkdownObjectRewriter rewriter, TestLoggerListener listener = null) - { - var pipelineBuilder = new MarkdownPipelineBuilder(); - var documentRewriter = new MarkdownDocumentVisitor(rewriter); - pipelineBuilder.DocumentProcessed += document => - { - ValidationExtension.SetSchemaName(document); - documentRewriter.Visit(document); - }; - var pipeline = pipelineBuilder.Build(); - - if (listener != null) - { - Logger.RegisterListener(listener); - } - - var html = Markdown.ToHtml(content, pipeline); - if (listener != null) - { - Logger.UnregisterListener(listener); - } - - return html; - } -}