using System; using System.Collections.Generic; using FluentValidation; using Gallium; using Nitride.Contents; using Zio; namespace Nitride.Markdown; /// /// An operation that identifies Markdown files by their common extensions /// and converts them to text input while also adding the IsMarkdown /// component to identify them. /// [WithProperties] public partial class IdentifyMarkdown : IOperation { private readonly IValidator validator; public IdentifyMarkdown(IValidator validator) { this.validator = validator; this.IsMarkdownTest = DefaultIsMarkdown; } public Func IsMarkdownTest { get; set; } /// public IEnumerable Run(IEnumerable input) { this.validator.ValidateAndThrow(this); return input.ForEachEntity(this.MarkTextEntities) .ForEachEntity(this.MarkBinaryEntities); } private static bool DefaultIsMarkdown(Entity entity, UPath path) { return (path.GetExtensionWithDot() ?? string.Empty).ToLowerInvariant() switch { ".md" => true, ".markdown" => true, _ => false, }; } private Entity MarkBinaryEntities(Entity entity, UPath path, IBinaryContent binary) { // If we aren't a Markdown file, then there is nothing // we can do about that. if (!this.IsMarkdownTest(entity, path)) { return entity; } // Convert the file as a binary. if (binary is ITextContentConvertable textConvertable) { entity = entity.SetTextContent(textConvertable.ToTextContent()).Set(IsMarkdown.Instance); } else { throw new InvalidOperationException( "Cannot convert a binary content to a " + "text without ITextContentConvertable."); } return entity; } private Entity MarkTextEntities(Entity entity, UPath path, ITextContent _) { // If we aren't a Markdown file, then there is nothing // we can do about that. if (!this.IsMarkdownTest(entity, path)) { return entity; } // We are already text, so just mark it as Markdown. entity = entity.Set(IsMarkdown.Instance); return entity; } }