Skip to content

Commit

Permalink
Refactor directive blocks to simplify properties handling. (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mpdreamz authored Jan 6, 2025
1 parent 6cac533 commit b8a151b
Show file tree
Hide file tree
Showing 16 changed files with 88 additions and 120 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ spelling_exclusion_path = "./build/exclusion.dic"

[*.{fs,fsx,cs,vb}]
file_header_template=Licensed to Elasticsearch B.V under one or more agreements.\nElasticsearch B.V licenses this file to you under the Apache 2.0 License.\nSee the LICENSE file in the project root for more information
max_line_length = 160

[*.{fs,fsx}]
indent_style = space
Expand Down
14 changes: 5 additions & 9 deletions src/Elastic.Markdown/Myst/Directives/AdmonitionBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
// See the LICENSE file in the project root for more information
namespace Elastic.Markdown.Myst.Directives;

public class AdmonitionBlock(
DirectiveBlockParser parser,
string admonition,
Dictionary<string, string> properties,
ParserContext context)
: DirectiveBlock(parser, properties, context)
public class DropdownBlock(DirectiveBlockParser parser, ParserContext context) : AdmonitionBlock(parser, "admonition", context);

public class AdmonitionBlock(DirectiveBlockParser parser, string admonition, ParserContext context)
: DirectiveBlock(parser, context)
{
public string Admonition => admonition == "admonition" ? Classes?.Trim() ?? "note" : admonition;

Expand All @@ -33,13 +31,11 @@ public string Title

public override void FinalizeAndValidate(ParserContext context)
{
CrossReferenceName = Properties.GetValueOrDefault("name");
CrossReferenceName = Prop("name");
DropdownOpen = TryPropBool("open");
if (DropdownOpen.HasValue)
Classes = "dropdown";
}
}


public class DropdownBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: AdmonitionBlock(parser, "admonition", properties, context);
3 changes: 1 addition & 2 deletions src/Elastic.Markdown/Myst/Directives/AppliesBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

namespace Elastic.Markdown.Myst.Directives;

public class AppliesBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: DirectiveBlock(parser, properties, context)
public class AppliesBlock(DirectiveBlockParser parser, ParserContext context) : DirectiveBlock(parser, context)
{
public override string Directive => "mermaid";

Expand Down
21 changes: 14 additions & 7 deletions src/Elastic.Markdown/Myst/Directives/DirectiveBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@ public interface IBlockExtension : IBlock
/// Initializes a new instance of the <see cref="DirectiveBlock"/> class.
/// </remarks>
/// <param name="parser">The parser used to create this block.</param>
/// <param name="properties"></param>
/// <param name="context"></param>
public abstract class DirectiveBlock(
DirectiveBlockParser parser,
Dictionary<string, string> properties,
ParserContext context
)
ParserContext context)
: ContainerBlock(parser), IFencedBlock, IBlockExtension
{
protected IReadOnlyDictionary<string, string> Properties { get; } = properties;
private Dictionary<string, string>? _properties;
protected IReadOnlyDictionary<string, string>? Properties => _properties;

public BuildContext Build { get; } = context.Build;

Expand Down Expand Up @@ -97,8 +95,15 @@ ParserContext context
/// <param name="context"></param>
public abstract void FinalizeAndValidate(ParserContext context);

protected bool PropBool(params string[] keys)
{
internal void AddProperty(string key, string value)
{
_properties ??= new Dictionary<string, string>();
_properties[key] = value;
}

protected bool PropBool(params string[] keys)
{
if (Properties is null) return false;
var value = Prop(keys);
if (string.IsNullOrEmpty(value))
return keys.Any(k => Properties.ContainsKey(k));
Expand All @@ -108,6 +113,7 @@ protected bool PropBool(params string[] keys)

protected bool? TryPropBool(params string[] keys)
{
if (Properties is null) return null;
var value = Prop(keys);
if (string.IsNullOrEmpty(value))
return keys.Any(k => Properties.ContainsKey(k)) ? true : null;
Expand All @@ -118,6 +124,7 @@ protected bool PropBool(params string[] keys)

protected string? Prop(params string[] keys)
{
if (Properties is null) return null;
foreach (var key in keys)
{
if (Properties.TryGetValue(key, out var value))
Expand Down
63 changes: 31 additions & 32 deletions src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ public DirectiveBlockParser()
InfoPrefix = null;
}

private Dictionary<string, string> _admonitionData = new();

private readonly string[] _admonitions = [ "important", "warning", "note", "tip" ];

private readonly string[] _versionBlocks = [ "versionadded", "versionchanged", "versionremoved", "deprecated" ];
Expand Down Expand Up @@ -67,7 +65,6 @@ public DirectiveBlockParser()

protected override DirectiveBlock CreateFencedBlock(BlockProcessor processor)
{
_admonitionData = new Dictionary<string, string>();
var info = processor.Line.AsSpan();

if (processor.Context is not ParserContext context)
Expand All @@ -76,57 +73,57 @@ protected override DirectiveBlock CreateFencedBlock(BlockProcessor processor)
// TODO alternate lookup .NET 9
var directive = info.ToString().Trim(['{', '}', '`']);
if (_unsupportedBlocks.TryGetValue(directive, out var issueId))
return new UnsupportedDirectiveBlock(this, directive, _admonitionData, issueId, context);
return new UnsupportedDirectiveBlock(this, directive, issueId, context);

if (info.IndexOf("{tab-set}") > 0)
return new TabSetBlock(this, _admonitionData, context);
return new TabSetBlock(this, context);

if (info.IndexOf("{tab-item}") > 0)
return new TabItemBlock(this, _admonitionData, context);
return new TabItemBlock(this, context);

if (info.IndexOf("{dropdown}") > 0)
return new DropdownBlock(this, _admonitionData, context);
return new DropdownBlock(this, context);

if (info.IndexOf("{image}") > 0)
return new ImageBlock(this, _admonitionData, context);
return new ImageBlock(this, context);

if (info.IndexOf("{figure}") > 0)
return new FigureBlock(this, _admonitionData, context);
return new FigureBlock(this, context);

if (info.IndexOf("{figure-md}") > 0)
return new FigureBlock(this, _admonitionData, context);
return new FigureBlock(this, context);

// this is currently listed as unsupported
// 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, context);
return new MermaidBlock(this, context);

if (info.IndexOf("{include}") > 0)
return new IncludeBlock(this, _admonitionData, context);
return new IncludeBlock(this, context);

if (info.IndexOf("{literalinclude}") > 0)
return new LiteralIncludeBlock(this, _admonitionData, context);
return new LiteralIncludeBlock(this, context);

if (info.IndexOf("{applies}") > 0)
return new AppliesBlock(this, _admonitionData, context);
return new AppliesBlock(this, context);

if (info.IndexOf("{settings}") > 0)
return new SettingsBlock(this, _admonitionData, context);
return new SettingsBlock(this, context);

foreach (var admonition in _admonitions)
{
if (info.IndexOf($"{{{admonition}}}") > 0)
return new AdmonitionBlock(this, admonition, _admonitionData, context);
return new AdmonitionBlock(this, admonition, context);
}

foreach (var version in _versionBlocks)
{
if (info.IndexOf($"{{{version}}}") > 0)
return new VersionBlock(this, version, _admonitionData, context);
return new VersionBlock(this, version, context);
}

return new UnknownDirectiveBlock(this, info.ToString(), _admonitionData, context);
return new UnknownDirectiveBlock(this, info.ToString(), context);
}

public override bool Close(BlockProcessor processor, Block block)
Expand All @@ -139,7 +136,7 @@ public override bool Close(BlockProcessor processor, Block block)

public override BlockState TryOpen(BlockProcessor processor)
{
if (processor.Context is not ParserContext context)
if (processor.Context is not ParserContext)
throw new Exception("Expected parser context to be of type ParserContext");

// We expect no indentation for a fenced code block.
Expand All @@ -164,19 +161,21 @@ public override BlockState TryContinue(BlockProcessor processor, Block block)
{
var line = processor.Line.AsSpan();

// TODO only parse this if no content proceeds it (and not in a code fence)
if (line.StartsWith(":"))
{
var tokens = line.ToString().Split(':', 3, RemoveEmptyEntries | TrimEntries);
if (tokens.Length < 1)
return base.TryContinue(processor, block);

var name = tokens[0];
var data = tokens.Length > 1 ? string.Join(":", tokens[1..]) : string.Empty;
_admonitionData[name] = data;
return BlockState.Continue;
}
if (!line.StartsWith(":"))
return base.TryContinue(processor, block);

if (block is not DirectiveBlock directiveBlock)
return base.TryContinue(processor, block);

var tokens = line.ToString().Split(':', 3, RemoveEmptyEntries | TrimEntries);
if (tokens.Length < 1)
return base.TryContinue(processor, block);

var name = tokens[0];
var data = tokens.Length > 1 ? string.Join(":", tokens[1..]) : string.Empty;
directiveBlock.AddProperty(name, data);

return BlockState.Continue;

return base.TryContinue(processor, block);
}
}
16 changes: 2 additions & 14 deletions src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,6 @@ private void WriteDropdown(HtmlRenderer renderer, DropdownBlock block)
RenderRazorSlice(slice, renderer, block);
}

private void WriteCode(HtmlRenderer renderer, EnhancedCodeBlock block)
{
var slice = Code.Create(new CodeViewModel
{
CrossReferenceName = string.Empty,// block.CrossReferenceName,
Language = block.Language,
Caption = string.Empty
});
//RenderRazorSliceRawContent(slice, renderer, block);
}


private void WriteTabSet(HtmlRenderer renderer, TabSetBlock block)
{
var slice = TabSet.Create(new TabSetViewModel());
Expand Down Expand Up @@ -232,7 +220,7 @@ private void WriteIncludeBlock(HtmlRenderer renderer, IncludeBlock block)
block.Configuration);
var file = block.FileSystem.FileInfo.New(block.IncludePath);
var document = parser.ParseAsync(file, block.FrontMatter, default).GetAwaiter().GetResult();
var html = document.ToHtml(parser.Pipeline);
var html = document.ToHtml(MarkdownParser.Pipeline);
renderer.Write(html);
//var slice = Include.Create(new IncludeViewModel { Html = html });
//RenderRazorSlice(slice, renderer, block);
Expand Down Expand Up @@ -270,7 +258,7 @@ private void WriteSettingsBlock(HtmlRenderer renderer, SettingsBlock block)
RenderMarkdown = s =>
{
var document = parser.Parse(s, block.IncludeFrom, block.FrontMatter);
var html = document.ToHtml(parser.Pipeline);
var html = document.ToHtml(MarkdownParser.Pipeline);
return html;
}
});
Expand Down
8 changes: 4 additions & 4 deletions src/Elastic.Markdown/Myst/Directives/ImageBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

namespace Elastic.Markdown.Myst.Directives;

public class ImageBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: DirectiveBlock(parser, properties, context)
public class FigureBlock(DirectiveBlockParser parser, ParserContext context) : ImageBlock(parser, context);

public class ImageBlock(DirectiveBlockParser parser, ParserContext context)
: DirectiveBlock(parser, context)
{
public override string Directive => "image";

Expand Down Expand Up @@ -100,5 +102,3 @@ private void ExtractImageUrl(ParserContext context)
}


public class FigureBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: ImageBlock(parser, properties, context);
21 changes: 9 additions & 12 deletions src/Elastic.Markdown/Myst/Directives/IncludeBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@

namespace Elastic.Markdown.Myst.Directives;

public class IncludeBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: DirectiveBlock(parser, properties, context)
public class LiteralIncludeBlock : IncludeBlock
{
public LiteralIncludeBlock(DirectiveBlockParser parser, ParserContext context) : base(parser, context) =>
Literal = true;

public override string Directive => "literalinclude";
}

public class IncludeBlock(DirectiveBlockParser parser, ParserContext context) : DirectiveBlock(parser, context)
{
public override string Directive => "include";

Expand Down Expand Up @@ -65,13 +72,3 @@ private void ExtractInclusionPath(ParserContext context)
this.EmitError($"`{IncludePath}` does not exist.");
}
}


public class LiteralIncludeBlock : IncludeBlock
{
public LiteralIncludeBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: base(parser, properties, context) => Literal = true;

public override string Directive => "literalinclude";

}
3 changes: 1 addition & 2 deletions src/Elastic.Markdown/Myst/Directives/MermaidBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
// See the LICENSE file in the project root for more information
namespace Elastic.Markdown.Myst.Directives;

public class MermaidBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: DirectiveBlock(parser, properties, context)
public class MermaidBlock(DirectiveBlockParser parser, ParserContext context) : DirectiveBlock(parser, context)
{
public override string Directive => "mermaid";

Expand Down
8 changes: 2 additions & 6 deletions src/Elastic.Markdown/Myst/Directives/SettingsBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

namespace Elastic.Markdown.Myst.Directives;

public class SettingsBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: DirectiveBlock(parser, properties, context)
public class SettingsBlock(DirectiveBlockParser parser, ParserContext context) : DirectiveBlock(parser, context)
{
public override string Directive => "settings";

Expand All @@ -32,10 +31,7 @@ public class SettingsBlock(DirectiveBlockParser parser, Dictionary<string, strin

//TODO add all options from
//https://mystmd.org/guide/directives#directive-include
public override void FinalizeAndValidate(ParserContext context)
{
ExtractInclusionPath(context);
}
public override void FinalizeAndValidate(ParserContext context) => ExtractInclusionPath(context);

private void ExtractInclusionPath(ParserContext context)
{
Expand Down
8 changes: 4 additions & 4 deletions src/Elastic.Markdown/Myst/Directives/TabSetBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

namespace Elastic.Markdown.Myst.Directives;

public class TabSetBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: DirectiveBlock(parser, properties, context)
public class TabSetBlock(DirectiveBlockParser parser, ParserContext context)
: DirectiveBlock(parser, context)
{
public override string Directive => "tab-set";

Expand All @@ -23,8 +23,8 @@ public int FindIndex()
return _index;
}
}
public class TabItemBlock(DirectiveBlockParser parser, Dictionary<string, string> properties, ParserContext context)
: DirectiveBlock(parser, properties, context)
public class TabItemBlock(DirectiveBlockParser parser, ParserContext context)
: DirectiveBlock(parser, context)
{
public override string Directive => "tab-item";

Expand Down
8 changes: 2 additions & 6 deletions src/Elastic.Markdown/Myst/Directives/UnknownDirectiveBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@

namespace Elastic.Markdown.Myst.Directives;

public class UnknownDirectiveBlock(
DirectiveBlockParser parser,
string directive,
Dictionary<string, string> properties,
ParserContext context)
: DirectiveBlock(parser, properties, context)
public class UnknownDirectiveBlock(DirectiveBlockParser parser, string directive, ParserContext context)
: DirectiveBlock(parser, context)
{
public override string Directive => directive;

Expand Down
Loading

0 comments on commit b8a151b

Please sign in to comment.