From 92f646892c11bbeb9e047cc11314af8da35b179b Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Tue, 12 Nov 2024 13:14:34 +0100 Subject: [PATCH] Introduce docset.yml --- .editorconfig | 12 +- docs/source/conf.py | 62 ------ docs/source/docset.yml | 16 ++ docs/source/elastic/index.md | 9 - docs/source/elastic/reference/index.md | 9 +- docs/source/elastic/search-labs/chat.md | 7 - docs/source/elastic/search-labs/index.md | 9 - docs/source/elastic/search-labs/install.md | 7 - docs/source/elastic/search-labs/search.md | 7 - docs/source/elastic/semantic-search/index.md | 10 - docs/source/index.md | 11 - docs/source/markup/index.md | 21 -- docs/source/multiversion_conf.py | 21 -- docs/source/nested/content/index.md | 5 - docs/source/nested/index.md | 6 - docs/source/theme_conf.py | 105 --------- docs/source/versioning/index.md | 5 - .../Diagnostics/DiagnosticsChannel.cs | 2 +- .../ProcessorDiagnosticExtensions.cs | 23 ++ src/Elastic.Markdown/IO/ConfigurationFile.cs | 207 ++++++++++++++++++ .../IO/DocumentationFolder.cs | 28 --- src/Elastic.Markdown/IO/DocumentationSet.cs | 4 + src/Elastic.Markdown/IO/MarkdownFile.cs | 10 - .../Myst/Directives/DirectiveBlockParser.cs | 24 +- .../Myst/Directives/DirectiveHtmlRenderer.cs | 3 - .../Myst/Directives/TocTreeBlock.cs | 22 -- .../Diagnostics/ErrorCollector.cs | 2 +- .../SiteMap/NavigationTests.cs | 4 +- 28 files changed, 263 insertions(+), 388 deletions(-) delete mode 100644 docs/source/conf.py create mode 100644 docs/source/docset.yml delete mode 100644 docs/source/multiversion_conf.py delete mode 100644 docs/source/theme_conf.py create mode 100644 src/Elastic.Markdown/IO/ConfigurationFile.cs delete mode 100644 src/Elastic.Markdown/Myst/Directives/TocTreeBlock.cs diff --git a/.editorconfig b/.editorconfig index 0f8ee8c..c4395e5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -136,12 +136,12 @@ csharp_style_var_for_built_in_types = true:error csharp_style_var_when_type_is_apparent = true:error csharp_style_var_elsewhere = true:error -csharp_style_expression_bodied_methods = true:warning -csharp_style_expression_bodied_constructors = true:warning -csharp_style_expression_bodied_operators = true:warning -csharp_style_expression_bodied_properties = true:warning -csharp_style_expression_bodied_indexers = true:warning -csharp_style_expression_bodied_accessors = true:warning +csharp_style_expression_bodied_methods = true:suggestion +csharp_style_expression_bodied_constructors = true:suggestion +csharp_style_expression_bodied_operators = true:suggestion +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_expression_bodied_indexers = true:suggestion +csharp_style_expression_bodied_accessors = true:suggestion # Suggest more modern language features when available csharp_style_pattern_matching_over_is_with_cast_check = true:error diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index c31d843..0000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,62 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information - -project = 'Elastic' -copyright = '2024, Elasticsearch B.V. All Rights Reserved.' - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -# If a project defines its own extension, the path to the extension -# should be added to the path so that Sphinx can find it. -import os -import sys -sys.path.append(os.path.abspath("./_ext")) - -extensions = [ - # Commenting out the myst_parser extensions, since it is already - # included in myst_nb. Including it again will cause an error. - #'myst_parser', - 'myst_nb', - 'sphinx_design', - 'sphinx.ext.duration', - 'sphinx_copybutton', - 'sphinx_togglebutton', - 'sphinxcontrib.mermaid', - 'sphinx_multiversion', - 'rejoin', - 'markitpy.extensions.yaml_to_md' -] - -templates_path = ['_templates'] -html_static_path = ['_static'] - -exclude_patterns = [] - -suppress_warnings = ["myst.strikethrough"] - -myst_enable_extensions = [ - 'substitution', - 'attrs_inline', - 'attrs_block', - 'tasklist', - 'strikethrough', - 'deflist' -] - -myst_substitutions = { - 'project': "MarkItPy", -} - -myst_title_to_header = True -# myst_heading_anchors = 0 - -this_dir = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(this_dir) -from theme_conf import * -from multiversion_conf import * diff --git a/docs/source/docset.yml b/docs/source/docset.yml new file mode 100644 index 0000000..7a8c022 --- /dev/null +++ b/docs/source/docset.yml @@ -0,0 +1,16 @@ +project: 'doc-builder' +exclude: + - '_*.md' +toc: + - file: index.md + - file: config.md + - file: search.md + children: + - file: search-part2.md + - folder: search + - folder: my-folder1 + - folder: my-folder2 + children: + - file: subpath/file.md + - file: file.md + - folder: sub/folder \ No newline at end of file diff --git a/docs/source/elastic/index.md b/docs/source/elastic/index.md index 8f47d8a..bd19393 100644 --- a/docs/source/elastic/index.md +++ b/docs/source/elastic/index.md @@ -10,12 +10,3 @@ Here's what we have so far: * [Search Labs Tutorial](search-labs/index.md) — A partial port of the Search Labs Tutorials content currently hosted [here](https://www.elastic.co/search-labs/tutorials). * [Automated Settings Reference](reference/index.md) — An example of an automatically automated setting * [Observability overview](observability/index.md) — Nothing special, just a bunch of images and text. - -```{toctree} -:hidden: - -Tutorial: Semantic search with the inference API -Search Labs -Automated Settings -Observability overview -``` \ No newline at end of file diff --git a/docs/source/elastic/reference/index.md b/docs/source/elastic/reference/index.md index cf6c160..55ebb6c 100644 --- a/docs/source/elastic/reference/index.md +++ b/docs/source/elastic/reference/index.md @@ -8,11 +8,4 @@ Simply supply a yaml spec and corresponding template file and content will be au This section includes one example yaml file and two auto-generated outputs based on that file: * [example `yaml` file](source.md) -* [generated output](generated.md) - -```{toctree} -:hidden: - -source.md -generated.md -``` \ No newline at end of file +* [generated output](generated.md) \ No newline at end of file diff --git a/docs/source/elastic/search-labs/chat.md b/docs/source/elastic/search-labs/chat.md index c4e4db5..699d81e 100644 --- a/docs/source/elastic/search-labs/chat.md +++ b/docs/source/elastic/search-labs/chat.md @@ -2,13 +2,6 @@ title: Chatbot Tutorial --- -```{toctree} -:hidden: - -chat/req.md -chat/rag.md -``` - In this tutorial you are going to build a large language model (LLM) chatbot that uses a pattern known as [Retrieval-Augmented Generation (RAG)](https://www.elastic.co/what-is/retrieval-augmented-generation). diff --git a/docs/source/elastic/search-labs/index.md b/docs/source/elastic/search-labs/index.md index d84dd3a..7ee685e 100644 --- a/docs/source/elastic/search-labs/index.md +++ b/docs/source/elastic/search-labs/index.md @@ -2,15 +2,6 @@ title: Search Labs Tutorials --- -```{toctree} -:hidden: - -install.md -search.md -chat.md -``` - - ## Start here ````{grid} 3 diff --git a/docs/source/elastic/search-labs/install.md b/docs/source/elastic/search-labs/install.md index 09f93e5..29b8337 100644 --- a/docs/source/elastic/search-labs/install.md +++ b/docs/source/elastic/search-labs/install.md @@ -2,13 +2,6 @@ title: "Install Elasticsearch" --- -```{toctree} -:hidden: - -install/cloud.md -install/docker.md -``` - In this section you will learn about some of the options you have for running Elasticsearch. Most of the tutorials and content on this site will require you to first follow the instructions below for your chosen method of installation. ## How to run Elasticsearch diff --git a/docs/source/elastic/search-labs/search.md b/docs/source/elastic/search-labs/search.md index 73fd835..9d318b4 100644 --- a/docs/source/elastic/search-labs/search.md +++ b/docs/source/elastic/search-labs/search.md @@ -2,13 +2,6 @@ title: "Search Tutorial" --- -```{toctree} -:hidden: - -search/req.md -search/setup.md -``` - Welcome! This hands-on tutorial will teach you how to build a complete search solution using [Elasticsearch](https://www.elastic.co/). In this tutorial you will learn: diff --git a/docs/source/elastic/semantic-search/index.md b/docs/source/elastic/semantic-search/index.md index 5e15241..70687f1 100644 --- a/docs/source/elastic/semantic-search/index.md +++ b/docs/source/elastic/semantic-search/index.md @@ -42,13 +42,3 @@ Amazon Bedrock examples use the `amazon.titan-embed-text-v1` model from the [Ama ```{tip} Not seeing the tutorial? Select a service above to get started. ``` - -```{toctree} -:hidden: - -Amazon Bedrock -Azure AI Studio -Azure OpenAI -Cohere -ELSER -``` diff --git a/docs/source/index.md b/docs/source/index.md index 6c2aa63..f4feea3 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -36,14 +36,3 @@ Hate it? Love it? We want to hear it all. Say hello and leave your thoughts in [ Hosted docs are great and all, but what's the contributor experience like? Read the [quick start guide](https://github.com/elastic/markitpy/tree/main), clone the repository, and spin up the docs locally in seconds. - - -```{toctree} -:caption: Elastic Docs Guide -:hidden: - -elastic/index.md -markup/index.md -nested/index.md -versioning/index.md -``` diff --git a/docs/source/markup/index.md b/docs/source/markup/index.md index 16591f8..d2ea0a3 100644 --- a/docs/source/markup/index.md +++ b/docs/source/markup/index.md @@ -3,24 +3,3 @@ title: Markup guide --- Here are some samples to show some features that you might want to use in your documentation. - -```{toctree} -:hidden: - -admonitions.md -tables.md -code.md -tabs.md -dropdowns.md -cards_grids.md -diagrams.md -images.md -sundries.md -substitutions.md -file_inclusion.md -extensions_with_roles_and_directives.md -yaml_to_markdown.md -notebook.ipynb -rst.rst -rst_in_markdown.md -``` diff --git a/docs/source/multiversion_conf.py b/docs/source/multiversion_conf.py deleted file mode 100644 index 8314b50..0000000 --- a/docs/source/multiversion_conf.py +++ /dev/null @@ -1,21 +0,0 @@ -# -- Options for sphinx-multiversion ----------------------------------------- -# https://holzhaus.github.io/sphinx-multiversion/master/configuration.html - -# Whitelist pattern for tags (set to None to ignore all tags) -# smv_tag_whitelist = None # Ignore all tags - -# Whitelist pattern for branches (set to None to ignore all branches) -# smv_branch_whitelist = r'^\d+\.\d+$' # Include branches like "2.1" -smv_branch_whitelist = r'^.*$' # Include all branches - -smv_remote_whitelist = None # Only use local branches -#smv_remote_whitelist = r'^.*$' # Use branches from all remotes - -# Pattern for released versions -# smv_released_pattern = r'^refs/heads/\d+\.\d+$' # Branches like "2.1" - -# Format for versioned output directories inside the build directory -#smv_outputdir_format = '{ref.name}' - -# Determines whether remote or local git branches/tags are preferred if their output dirs conflict -#smv_prefer_remote_refs = False \ No newline at end of file diff --git a/docs/source/nested/content/index.md b/docs/source/nested/content/index.md index e6aaf23..dca6303 100644 --- a/docs/source/nested/content/index.md +++ b/docs/source/nested/content/index.md @@ -4,8 +4,3 @@ title: Content Welcome to Nested Content. -```{toctree} -:hidden: - -nest-cafe.md -``` diff --git a/docs/source/nested/index.md b/docs/source/nested/index.md index 2dafbc8..4143057 100644 --- a/docs/source/nested/index.md +++ b/docs/source/nested/index.md @@ -3,9 +3,3 @@ title: Nested content --- This bucket is an example of nested content. Head down the tree to see how it works. - -```{toctree} -:hidden: - -content/index.md -``` \ No newline at end of file diff --git a/docs/source/theme_conf.py b/docs/source/theme_conf.py deleted file mode 100644 index 6d9eaa0..0000000 --- a/docs/source/theme_conf.py +++ /dev/null @@ -1,105 +0,0 @@ -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = "shibuya" - -html_theme_options = { - "announcement": '
👋 Thanks for checking out our Elastic Docs v3 POC. Have feedback? Reach out here. Thanks!
', - "light_logo": "_static/logo-light.svg", - "dark_logo": "_static/logo-dark.svg", - "accent_color": "blue", - "globaltoc_expand_depth": 1, - "logo_target": "index.html", - "nav_links": [ - { - "title": "Elastic Docs v3", - "url": "index" - }, - { - "title": "Start Here", - "children": [ - { - "title": "Search", - "url": "index", - "summary": "Build custom applications with your data using Elasticsearch.", - }, - { - "title": "Observability", - "url": "index", - "summary": "Monitor applications and systems with Elastic Observability.", - }, - { - "title": "Security", - "url": "index", - "summary": "Detect, investigate, and respond to threats with Elastic Security.", - }, - ] - }, - { - "title": "Deploy", - "children": [ - { - "title": "Elastic Cloud", - "url": "index", - "summary": "Deploy instances of the Elastic Stack in the cloud, with the provider of your choice." - }, - { - "title": "Elastic Cloud Enterprise", - "url": "index", - "summary": "Deploy Elastic Cloud on public or private clouds, virtual machines, or your own premises." - }, - { - "title": "Elastic Cloud on Kubernetes", - "url": "index", - "summary": "Deploy Elastic Cloud on Kubernetes." - }, - { - "title": "Self managed", - "url": "index", - "summary": "Install, configure, and run Elastic products on your own premises." - } - ] - }, - { - "title": "Reference", - "children": [ - { - "title": "API Reference", - "url": "index", - "summary": "Description." - }, - { - "title": "Configuration Reference", - "url": "index", - "summary": "Description." - }, - { - "title": "Troubleshooting", - "url": "index", - "summary": "Description." - }, - ] - }, - { - "title": "What's New", - "url": "index" - } - ] -} - -html_context = { - "source_type": "github", - "source_user": "elastic", - "source_repo": "markitpy-samples", - "source_version": "master", # Optional - "source_docs_path": "/docs/source/", # Optional -} - -html_css_files = ["custom.css"] - -html_sidebars = { - "**": [ - "sidebars/localtoc.html", - "sidebars/edit-this-page.html", - ] -} diff --git a/docs/source/versioning/index.md b/docs/source/versioning/index.md index 4939ddf..c4e16de 100644 --- a/docs/source/versioning/index.md +++ b/docs/source/versioning/index.md @@ -9,8 +9,3 @@ Multiversion support This file demonstrates versioning support. See the `markitpy` readme to learn how to test this content. -```{toctree} -:hidden: - -versioned.md -``` diff --git a/src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs b/src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs index d69fc7a..9522dce 100644 --- a/src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs +++ b/src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs @@ -47,7 +47,7 @@ public enum Severity { Error, Warning } public readonly record struct Diagnostic { public Severity Severity { get; init; } - public int Line { get; init; } + public int? Line { get; init; } public int? Column { get; init; } public int? Length { get; init; } public string File { get; init; } diff --git a/src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs b/src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs index bf67147..dc7ada5 100644 --- a/src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs +++ b/src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs @@ -2,6 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information +using System.IO.Abstractions; using Elastic.Markdown.Myst; using Markdig.Helpers; using Markdig.Parsers; @@ -72,4 +73,26 @@ public static void EmitWarning(this ParserContext context, int line, int column, }; context.Build.Collector.Channel.Write(d); } + + public static void EmitError(this BuildContext context, IFileInfo file, string message) + { + var d = new Diagnostic + { + Severity = Severity.Error, + File = file.FullName, + Message = message, + }; + context.Collector.Channel.Write(d); + } + + public static void EmitWarning(this BuildContext context, IFileInfo file, string message) + { + var d = new Diagnostic + { + Severity = Severity.Error, + File = file.FullName, + Message = message, + }; + context.Collector.Channel.Write(d); + } } diff --git a/src/Elastic.Markdown/IO/ConfigurationFile.cs b/src/Elastic.Markdown/IO/ConfigurationFile.cs new file mode 100644 index 0000000..245fef9 --- /dev/null +++ b/src/Elastic.Markdown/IO/ConfigurationFile.cs @@ -0,0 +1,207 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using System.Data.SqlTypes; +using System.IO.Abstractions; +using Cysharp.IO; +using Elastic.Markdown.Diagnostics; +using Markdig.Helpers; +using YamlDotNet.Core; +using YamlDotNet.RepresentationModel; + +namespace Elastic.Markdown.IO; + +public class ConfigurationFile : DocumentationFile +{ + private readonly IFileInfo _sourceFile; + private readonly BuildContext _context; + public string? Project { get; } + public string[] Exclude { get; } = []; + + public IReadOnlyCollection TableOfContents { get; } = []; + + public ConfigurationFile(IFileInfo sourceFile, IDirectoryInfo rootPath, BuildContext context) + : base(sourceFile, rootPath) + { + _sourceFile = sourceFile; + _context = context; + if (!sourceFile.Exists) + { + Project = "unknown"; + TableOfContents = []; + context.EmitWarning(sourceFile, "No configuration file found"); + return; + } + + // Load the stream + var yaml = new YamlStream(); + var textReader = sourceFile.FileSystem.File.OpenText(sourceFile.FullName); + yaml.Load(textReader); + + if (yaml.Documents.Count == 0) + context.EmitWarning(sourceFile, "empty configuration"); + + // Examine the stream + var mapping = (YamlMappingNode)yaml.Documents[0].RootNode; + + foreach (var entry in mapping.Children) + { + var key = ((YamlScalarNode)entry.Key).Value; + switch (key) + { + case "project": + Project = ReadString(entry); + break; + case "exclude": + Exclude = ReadStringArray(entry) ?? []; + break; + case "toc": + var entries = ReadChildren(entry); + + TableOfContents = entries; + break; + default: + EmitWarning($"{key} is not a known configuration", entry.Key); + break; + } + } + + } + + private List ReadChildren(KeyValuePair entry) + { + var entries = new List(); + if (entry.Value is not YamlSequenceNode sequence) + { + var key = ((YamlScalarNode)entry.Key).Value; + EmitWarning($"'{key}' is not an array"); + return entries; + } + + foreach (var tocEntry in sequence.Children.OfType()) + { + var tocItem = ReadChild(tocEntry); + if (tocItem is not null) + entries.Add(tocItem); + } + + return entries; + } + + private ITocItem? ReadChild(YamlMappingNode tocEntry) + { + string? file = null; + string? folder = null; + IReadOnlyCollection? children = null; + foreach (var entry in tocEntry.Children) + { + var key = ((YamlScalarNode)entry.Key).Value; + switch (key) + { + case "file": + file = ReadString(entry); + break; + case "folder": + folder = ReadString(entry); + break; + case "children": + children = ReadChildren(entry); + break; + } + } + + if (file is not null) + return new TocFile(file, children); + if (folder is not null) + return new TocFile(folder, children); + + return null; + } + + private string? ReadString(KeyValuePair entry) + { + if (entry.Value is YamlScalarNode scalar) + return scalar.Value; + + var key = ((YamlScalarNode)entry.Key).Value; + + EmitError($"'{key}' is not a string", entry.Key); + return null; + } + private string[]? ReadStringArray(KeyValuePair entry) + { + var values = new List(); + if (entry.Value is YamlSequenceNode sequence) + { + foreach (var entryValue in sequence.Children.OfType()) + { + if (entryValue.Value is not null) + values.Add(entryValue.Value); + } + + } + return values.ToArray(); + } + + public void EmitError(string message, YamlNode? node) => EmitError(message, node?.Start, node?.End); + + public void EmitWarning(string message, YamlNode? node) => EmitError(message, node?.Start, node?.End); + + public void EmitError(string message, Mark? start = null, Mark? end = null) + { + var d = new Diagnostic + { + Severity = Severity.Error, + File = _sourceFile.FullName, + Message = message, + Line = start.HasValue ? (int)start.Value.Line : null, + Column = start.HasValue ? (int)start.Value.Column : null, + Length = start.HasValue && end.HasValue ? (int)start.Value.Column - (int)end.Value.Column : null + }; + _context.Collector.Channel.Write(d); + } + + public void EmitWarning(string message, Mark? start = null, Mark? end = null) + { + var d = new Diagnostic + { + Severity = Severity.Warning, + File = _sourceFile.FullName, + Message = message, + Line = start.HasValue ? (int)start.Value.Line : null, + Column = start.HasValue ? (int)start.Value.Column : null, + Length = start.HasValue && end.HasValue ? (int)start.Value.Column - (int)end.Value.Column : null + }; + _context.Collector.Channel.Write(d); + } +} + +public interface ITocItem; + +public record TocFile(string Path, IReadOnlyCollection? Children) : ITocItem; + +public record TocFolder(string Path, IReadOnlyCollection? Children) : ITocItem; + + +/* +exclude: + - notes.md + - '**ignore.md' +toc: +- file: index.md +- file: config.md +- file: search.md +children: +- file: search-part2.md +- folder: search +- folder: my-folder1 +exclude: +- '_*.md' +- folder: my-folder2 +children: +- file: subpath/file.md +- file: file.md +- pattern: *.md +- folder: sub/folder +*/ diff --git a/src/Elastic.Markdown/IO/DocumentationFolder.cs b/src/Elastic.Markdown/IO/DocumentationFolder.cs index c0fb442..a5e3b13 100644 --- a/src/Elastic.Markdown/IO/DocumentationFolder.cs +++ b/src/Elastic.Markdown/IO/DocumentationFolder.cs @@ -69,39 +69,11 @@ public async Task Resolve(Cancel ctx = default) await Parallel.ForEachAsync(Files, ctx, async (file, token) => await file.ParseAsync(token)); await Parallel.ForEachAsync(Nested, ctx, async (group, token) => await group.Resolve(token)); - //foreach (var f in Files) await f.ParseAsync(ctx); - //foreach (var n in Nested) await n.Resolve(ctx); - await (Index?.ParseAsync(ctx) ?? Task.CompletedTask); - if (Index?.TocTree == null) - return; - var tree = Index.TocTree; var fileList = new OrderedList(); var groupList = new OrderedList(); - foreach (var link in tree) - { - var file = Files.FirstOrDefault(f => f.RelativePath.EndsWith(link.Link)); - if (file != null) - { - file.TocTitle = link.Title; - fileList.Add(file); - continue; - } - - var group = Nested.FirstOrDefault(f => f.Index != null && f.Index.RelativePath.EndsWith(link.Link)); - if (group != null) - { - groupList.Add(group); - if (group.Index != null && !string.IsNullOrEmpty(link.Title)) - group.Index.TocTitle = link.Title; - } - else if (group == null || file == null) - { - - } - } FilesInOrder = fileList; GroupsInOrder = groupList; diff --git a/src/Elastic.Markdown/IO/DocumentationSet.cs b/src/Elastic.Markdown/IO/DocumentationSet.cs index a98fa63..b3422fd 100644 --- a/src/Elastic.Markdown/IO/DocumentationSet.cs +++ b/src/Elastic.Markdown/IO/DocumentationSet.cs @@ -17,6 +17,7 @@ public class DocumentationSet public DateTimeOffset LastWrite { get; } public IFileInfo OutputStateFile { get; } + public ConfigurationFile Configuration { get; } private MarkdownParser MarkdownParser { get; } @@ -30,6 +31,9 @@ public DocumentationSet(IDirectoryInfo? sourcePath, IDirectoryInfo? outputPath, MarkdownParser = new MarkdownParser(SourcePath, context); OutputStateFile = OutputPath.FileSystem.FileInfo.New(Path.Combine(OutputPath.FullName, ".doc.state")); + var configurationFile = context.ReadFileSystem.FileInfo.New(Path.Combine(SourcePath.FullName, "docset.yml")); + Configuration = new ConfigurationFile(configurationFile, SourcePath, context); + Files = context.ReadFileSystem.Directory.EnumerateFiles(SourcePath.FullName, "*.*", SearchOption.AllDirectories) .Select(f => context.ReadFileSystem.FileInfo.New(f)) .Select(file => file.Extension switch diff --git a/src/Elastic.Markdown/IO/MarkdownFile.cs b/src/Elastic.Markdown/IO/MarkdownFile.cs index 3e2ec2b..dfd8d29 100644 --- a/src/Elastic.Markdown/IO/MarkdownFile.cs +++ b/src/Elastic.Markdown/IO/MarkdownFile.cs @@ -55,14 +55,6 @@ public async Task ParseFullAsync(Cancel ctx) Title = YamlFrontMatter.Title; } - if (SourceFile.Name == "index.md") - { - TocTree = document - .Where(block => block is TocTreeBlock) - .Cast() - .FirstOrDefault()?.Links ?? new OrderedList(); - } - var contents = document .Where(block => block is HeadingBlock { Level: 2 }) .Cast() @@ -75,8 +67,6 @@ public async Task ParseFullAsync(Cancel ctx) return document; } - public OrderedList? TocTree { get; private set; } - public async Task CreateHtmlAsync(YamlFrontMatter? matter, Cancel ctx) { var document = await MarkdownParser.ParseAsync(SourceFile, matter, ctx); diff --git a/src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs b/src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs index ccb0b39..bfdf190 100644 --- a/src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs +++ b/src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs @@ -70,10 +70,6 @@ protected override DirectiveBlock CreateFencedBlock(BlockProcessor processor) if (processor.Context is not ParserContext context) throw new Exception("Expected parser context to be of type ParserContext"); - - if (info.EndsWith("{toctree}")) - return new TocTreeBlock(this, _admonitionData); - if (info.IndexOf("{") == -1) return new CodeBlock(this, "raw", _admonitionData); @@ -101,7 +97,7 @@ protected override DirectiveBlock CreateFencedBlock(BlockProcessor processor) return new FigureBlock(this, _admonitionData, context); // this is currently listed as unsupported - // leaving the parsing in untill we are confident we don't want this + // leaving the parsing in until we are confident we don't want this // for dev-docs if (info.IndexOf("{mermaid}") > 0) return new MermaidBlock(this, _admonitionData); @@ -137,23 +133,7 @@ public override bool Close(BlockProcessor processor, Block block) if (block is DirectiveBlock directiveBlock) directiveBlock.FinalizeAndValidate(processor.GetContext()); - - if (block is not TocTreeBlock toc) - return base.Close(processor, block); - - if (toc is not { Count: > 0 } || toc[0] is not ParagraphBlock p) - return base.Close(processor, block); - - var text = p.Lines.ToSlice().AsSpan().ToString(); - foreach (var line in text.Split('\n')) - { - var tokens = line.Split('<', '>').Where(e => !string.IsNullOrWhiteSpace(e)).ToArray(); - var fileName = tokens.Last().Trim(); - var title = string.Join(" ", tokens.Take(tokens.Length - 1)).Trim(); - toc.Links.Add(new TocTreeLink { Title = title, Link = fileName }); - } - - return base.Close(processor, block); + return base.Close(processor, block); } public override BlockState TryContinue(BlockProcessor processor, Block block) diff --git a/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs b/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs index 7570290..806976a 100644 --- a/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs +++ b/src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs @@ -26,9 +26,6 @@ public class DirectiveHtmlRenderer : HtmlObjectRenderer { protected override void Write(HtmlRenderer renderer, DirectiveBlock directiveBlock) { - if (directiveBlock is TocTreeBlock) - return; - renderer.EnsureLine(); switch (directiveBlock) diff --git a/src/Elastic.Markdown/Myst/Directives/TocTreeBlock.cs b/src/Elastic.Markdown/Myst/Directives/TocTreeBlock.cs deleted file mode 100644 index ef72554..0000000 --- a/src/Elastic.Markdown/Myst/Directives/TocTreeBlock.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to Elasticsearch B.V under one or more agreements. -// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. -// See the LICENSE file in the project root for more information -using Markdig.Helpers; - -namespace Elastic.Markdown.Myst.Directives; - -public class TocTreeLink -{ - public required string Link { get; init; } - public string? Title { get; set; } -} - -public class TocTreeBlock(DirectiveBlockParser parser, Dictionary properties) - : DirectiveBlock(parser, properties) -{ - public OrderedList Links { get; } = new(); - - public override void FinalizeAndValidate(ParserContext context) - { - } -} diff --git a/src/docs-builder/Diagnostics/ErrorCollector.cs b/src/docs-builder/Diagnostics/ErrorCollector.cs index 4986b33..d10a13a 100644 --- a/src/docs-builder/Diagnostics/ErrorCollector.cs +++ b/src/docs-builder/Diagnostics/ErrorCollector.cs @@ -66,7 +66,7 @@ public override async Task StopAsync(Cancel ctx) { Severity.Error => Errata.Diagnostic.Error(item.Message) - .WithLabel(new Label(item.File, new Location(item.Line, item.Column ?? 0), "bad substitution") + .WithLabel(new Label(item.File, new Location(item.Line ?? 0, item.Column ?? 0), "bad substitution") .WithLength(item.Length ?? 3) .WithPriority(1) .WithColor(Color.Red)), diff --git a/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs b/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs index 2c158de..67972e1 100644 --- a/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs +++ b/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs @@ -38,8 +38,8 @@ public async Task CreatesDefaultOutputDirectory() await generator.GenerateAll(default); - writeFs.Directory.Exists(".artifacts/docs/html").Should().BeTrue(); - readFs.Directory.Exists(".artifacts/docs/html").Should().BeFalse(); + var configuration = generator.DocumentationSet.Configuration; + configuration.TableOfContents.Should().NotBeNullOrEmpty(); } }