|
9 | 9 | using Elastic.Markdown.Myst.Directives.Diagram;
|
10 | 10 | using Elastic.Markdown.Myst.Directives.Image;
|
11 | 11 | using Elastic.Markdown.Myst.Directives.Include;
|
| 12 | +using Elastic.Markdown.Myst.Directives.Settings; |
12 | 13 | using Markdig.Extensions.DefinitionLists;
|
13 | 14 | using Markdig.Extensions.Tables;
|
14 | 15 | using Markdig.Extensions.Yaml;
|
15 | 16 | using Markdig.Renderers;
|
16 | 17 | using Markdig.Syntax;
|
17 | 18 | using Markdig.Syntax.Inlines;
|
| 19 | +using YamlDotNet.Core; |
18 | 20 | using CodeBlock = Markdig.Syntax.CodeBlock;
|
19 | 21 |
|
20 | 22 | namespace Elastic.Markdown.Myst.Renderers.LlmMarkdown;
|
@@ -388,6 +390,9 @@ protected override void Write(LlmMarkdownRenderer renderer, DirectiveBlock obj)
|
388 | 390 | case DiagramBlock diagramBlock:
|
389 | 391 | WriteDiagramBlock(renderer, diagramBlock);
|
390 | 392 | return;
|
| 393 | + case SettingsBlock settingsBlock: |
| 394 | + WriteSettingsBlock(renderer, settingsBlock); |
| 395 | + return; |
391 | 396 | }
|
392 | 397 |
|
393 | 398 | // Ensure single empty line before directive
|
@@ -509,6 +514,99 @@ private void WriteIncludeBlock(LlmMarkdownRenderer renderer, IncludeBlock block)
|
509 | 514 | renderer.EnsureLine();
|
510 | 515 | }
|
511 | 516 |
|
| 517 | + private void WriteSettingsBlock(LlmMarkdownRenderer renderer, SettingsBlock block) |
| 518 | + { |
| 519 | + if (!block.Found || block.IncludePath is null) |
| 520 | + { |
| 521 | + var path = block.IncludePath ?? "(no path specified)"; |
| 522 | + renderer.BuildContext.Collector.EmitError( |
| 523 | + block.IncludePath ?? string.Empty, |
| 524 | + $"Settings directive error: Could not resolve path '{path}'. Ensure the file exists and the path is correct."); |
| 525 | + return; |
| 526 | + } |
| 527 | + |
| 528 | + var file = block.Build.ReadFileSystem.FileInfo.New(block.IncludePath); |
| 529 | + |
| 530 | + // Check if file exists before attempting to read |
| 531 | + if (!file.Exists) |
| 532 | + { |
| 533 | + renderer.BuildContext.Collector.EmitError( |
| 534 | + block.IncludePath, |
| 535 | + $"Settings file not found: '{block.IncludePath}' does not exist. Check that the file path is correct and the file has been committed to the repository."); |
| 536 | + return; |
| 537 | + } |
| 538 | + |
| 539 | + YamlSettings? settings; |
| 540 | + try |
| 541 | + { |
| 542 | + var yaml = file.FileSystem.File.ReadAllText(file.FullName); |
| 543 | + settings = YamlSerialization.Deserialize<YamlSettings>(yaml, block.Context.Build.ProductsConfiguration); |
| 544 | + } |
| 545 | + catch (FileNotFoundException e) |
| 546 | + { |
| 547 | + renderer.BuildContext.Collector.EmitError( |
| 548 | + block.IncludePath, |
| 549 | + $"Settings file not found: Unable to read '{block.IncludePath}'. The file may have been moved or deleted.", |
| 550 | + e); |
| 551 | + return; |
| 552 | + } |
| 553 | + catch (DirectoryNotFoundException e) |
| 554 | + { |
| 555 | + renderer.BuildContext.Collector.EmitError( |
| 556 | + block.IncludePath, |
| 557 | + $"Settings directory not found: The directory containing '{block.IncludePath}' does not exist. Check that the path is correct.", |
| 558 | + e); |
| 559 | + return; |
| 560 | + } |
| 561 | + catch (YamlException e) |
| 562 | + { |
| 563 | + renderer.BuildContext.Collector.EmitError( |
| 564 | + block.IncludePath, |
| 565 | + $"Invalid YAML in settings file: '{block.IncludePath}' contains invalid YAML syntax. Please check the file format matches the expected settings structure (groups, settings, etc.).", |
| 566 | + e.InnerException ?? e); |
| 567 | + return; |
| 568 | + } |
| 569 | + catch (Exception e) |
| 570 | + { |
| 571 | + renderer.BuildContext.Collector.EmitError( |
| 572 | + block.IncludePath, |
| 573 | + $"Failed to process settings file: Unable to parse '{block.IncludePath}'. Error: {e.Message}", |
| 574 | + e); |
| 575 | + return; |
| 576 | + } |
| 577 | + |
| 578 | + renderer.EnsureBlockSpacing(); |
| 579 | + |
| 580 | + foreach (var group in settings.Groups) |
| 581 | + { |
| 582 | + renderer.WriteLine(); |
| 583 | + renderer.Write("## "); |
| 584 | + renderer.WriteLine(group.Name ?? string.Empty); |
| 585 | + |
| 586 | + foreach (var setting in group.Settings) |
| 587 | + { |
| 588 | + renderer.WriteLine(); |
| 589 | + renderer.Write("#### "); |
| 590 | + renderer.WriteLine(setting.Name ?? string.Empty); |
| 591 | + |
| 592 | + if (!string.IsNullOrEmpty(setting.Description)) |
| 593 | + { |
| 594 | + var document = MarkdownParser.ParseMarkdownStringAsync( |
| 595 | + block.Build, |
| 596 | + block.Context, |
| 597 | + setting.Description, |
| 598 | + block.IncludeFrom, |
| 599 | + block.Context.YamlFrontMatter, |
| 600 | + MarkdownParser.Pipeline); |
| 601 | + _ = renderer.Render(document); |
| 602 | + renderer.EnsureBlockSpacing(); |
| 603 | + } |
| 604 | + } |
| 605 | + } |
| 606 | + |
| 607 | + renderer.EnsureLine(); |
| 608 | + } |
| 609 | + |
512 | 610 | private static void WriteChildrenWithIndentation(LlmMarkdownRenderer renderer, Block container, string indent)
|
513 | 611 | {
|
514 | 612 | // Capture output and manually add indentation
|
|
0 commit comments