Skip to content

Commit a95d0b2

Browse files
committed
Cleanup
1 parent 0409a33 commit a95d0b2

File tree

2 files changed

+40
-136
lines changed

2 files changed

+40
-136
lines changed

src/Elastic.Markdown/Myst/Renderers/LlmMarkdown/LlmBlockRenderers.cs

Lines changed: 39 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,8 @@
1818

1919
namespace Elastic.Markdown.Myst.Renderers.LlmMarkdown;
2020

21-
/// <summary>
22-
/// Helper methods for common rendering patterns in LLM renderers
23-
/// </summary>
2421
public static class LlmRenderingHelpers
2522
{
26-
/// <summary>
27-
/// Renders a block with fixed indentation applied to each line
28-
/// </summary>
29-
/// <param name="renderer">The target renderer to write to</param>
30-
/// <param name="block">The block to render</param>
31-
/// <param name="indentation">The indentation string to apply to each line (default: 2 spaces)</param>
3223
public static void RenderBlockWithIndentation(LlmMarkdownRenderer renderer, MarkdownObject block, string indentation = " ")
3324
{
3425
using var tempWriter = new StringWriter();
@@ -37,17 +28,14 @@ public static void RenderBlockWithIndentation(LlmMarkdownRenderer renderer, Mark
3728
BuildContext = renderer.BuildContext // Copy BuildContext for URL transformation
3829
};
3930
_ = tempRenderer.Render(block);
40-
41-
// Get the rendered content and add indentation to each line
4231
var content = tempWriter.ToString().TrimEnd();
43-
if (!string.IsNullOrEmpty(content))
32+
if (string.IsNullOrEmpty(content))
33+
return;
34+
var lines = content.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries);
35+
foreach (var line in lines)
4436
{
45-
var lines = content.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries);
46-
foreach (var line in lines)
47-
{
48-
renderer.Write(indentation);
49-
renderer.WriteLine(line);
50-
}
37+
renderer.Write(indentation);
38+
renderer.WriteLine(line);
5139
}
5240
}
5341

@@ -56,30 +44,22 @@ public static void RenderBlockWithIndentation(LlmMarkdownRenderer renderer, Mark
5644
/// </summary>
5745
public static string? MakeAbsoluteUrl(LlmMarkdownRenderer renderer, string? url)
5846
{
59-
if (string.IsNullOrEmpty(url) || renderer.BuildContext.CanonicalBaseUrl == null)
60-
return url;
61-
62-
// If URL is already absolute, return as-is
63-
if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
47+
if (
48+
string.IsNullOrEmpty(url)
49+
|| renderer.BuildContext.CanonicalBaseUrl == null
50+
|| Uri.IsWellFormedUriString(url, UriKind.Absolute)
51+
|| !Uri.IsWellFormedUriString(url, UriKind.Relative))
6452
return url;
65-
66-
// If URL is relative, prepend canonical base URL
67-
if (Uri.IsWellFormedUriString(url, UriKind.Relative))
53+
try
6854
{
69-
try
70-
{
71-
var baseUri = renderer.BuildContext.CanonicalBaseUrl;
72-
var absoluteUri = new Uri(baseUri, url);
73-
return absoluteUri.ToString();
74-
}
75-
catch
76-
{
77-
// If URI construction fails, return original URL
78-
return url;
79-
}
55+
var baseUri = renderer.BuildContext.CanonicalBaseUrl;
56+
var absoluteUri = new Uri(baseUri, url);
57+
return absoluteUri.ToString();
58+
}
59+
catch
60+
{
61+
return url;
8062
}
81-
82-
return url;
8363
}
8464
}
8565

@@ -91,90 +71,70 @@ public class LlmYamlFrontMatterRenderer : MarkdownObjectRenderer<LlmMarkdownRend
9171
protected override void Write(LlmMarkdownRenderer renderer, YamlFrontMatterBlock obj)
9272
{
9373
// Intentionally skip rendering YAML frontmatter - it should not appear in LLM output
94-
// The frontmatter content is already processed and available through context.SourceFile.YamlFrontMatter
74+
// The frontmatter content is currently handled in LlmMarkdownExporter.cs
75+
// TODO: Handle YAML frontmatter in LLM output here
9576
}
9677
}
9778

98-
/// <summary>
99-
/// Renders headings as clean CommonMark headings with improved spacing for readability
100-
/// </summary>
10179
public class LlmHeadingRenderer : MarkdownObjectRenderer<LlmMarkdownRenderer, HeadingBlock>
10280
{
10381
protected override void Write(LlmMarkdownRenderer renderer, HeadingBlock obj)
10482
{
105-
// Add extra spacing before headings - always add multiple newlines
106-
renderer.Writer.WriteLine();
107-
renderer.Writer.WriteLine();
83+
renderer.EnsureBlockSpacing();
84+
renderer.WriteLine();
10885

109-
// Extract just the text content for clean headings
11086
var headingText = ExtractHeadingText(obj);
11187

112-
// Output as standard markdown heading
113-
renderer.Writer.Write(new string('#', obj.Level));
114-
renderer.Writer.Write(' ');
88+
renderer.Write(new string('#', obj.Level));
89+
renderer.Write(" ");
11590
renderer.WriteLine(headingText);
11691
}
11792

11893
private static string ExtractHeadingText(HeadingBlock heading)
11994
{
12095
if (heading.Inline == null)
12196
return string.Empty;
122-
123-
// Extract plain text from inline elements
12497
return heading.Inline.Descendants()
12598
.OfType<Markdig.Syntax.Inlines.LiteralInline>()
12699
.Select(l => l.Content.ToString())
127100
.Aggregate(string.Empty, (current, text) => current + text);
128101
}
129102
}
130103

131-
/// <summary>
132-
/// Renders paragraphs with proper spacing for LLM readability
133-
/// </summary>
134104
public class LlmParagraphRenderer : MarkdownObjectRenderer<LlmMarkdownRenderer, ParagraphBlock>
135105
{
136106
protected override void Write(LlmMarkdownRenderer renderer, ParagraphBlock obj)
137107
{
108+
// Only add newline if the paragraph is not within an element
138109
if (obj.Parent is MarkdownDocument)
139110
renderer.EnsureBlockSpacing();
140111
renderer.WriteLeafInline(obj);
141112
renderer.EnsureLine();
142113
}
143114
}
144115

145-
/// <summary>
146-
/// Renders enhanced code blocks (your custom extension) as standard code blocks with optional metadata
147-
/// and improved spacing for readability
148-
/// </summary>
149-
public partial class LlmEnhancedCodeBlockRenderer : MarkdownObjectRenderer<LlmMarkdownRenderer, EnhancedCodeBlock>
116+
public class LlmEnhancedCodeBlockRenderer : MarkdownObjectRenderer<LlmMarkdownRenderer, EnhancedCodeBlock>
150117
{
151118
protected override void Write(LlmMarkdownRenderer renderer, EnhancedCodeBlock obj)
152119
{
153-
// Ensure single empty line before code block
154120
renderer.EnsureBlockSpacing();
155-
156-
// Add caption as comment if present
157121
if (!string.IsNullOrEmpty(obj.Caption))
158122
{
159123
renderer.Write("<!-- Caption: ");
160124
renderer.Write(obj.Caption);
161125
renderer.WriteLine(" -->");
162126
}
163-
164127
renderer.Write("```");
165128
if (!string.IsNullOrEmpty(obj.Language))
166129
renderer.Write(obj.Language);
167130
renderer.WriteLine();
168-
169131
var lastNonEmptyIndex = GetLastNonEmptyLineIndex(obj);
170132
for (var i = 0; i <= lastNonEmptyIndex; i++)
171133
{
172134
var line = obj.Lines.Lines[i];
173135
renderer.Write(line.ToString());
174136
renderer.WriteLine();
175137
}
176-
177-
// Close code block
178138
renderer.WriteLine("```");
179139
}
180140

@@ -226,15 +186,9 @@ protected override void Write(LlmMarkdownRenderer renderer, ListBlock listBlock)
226186
}
227187
}
228188

229-
/// <summary>
230-
/// Gets the continuation indent for multi-line list items
231-
/// </summary>
232189
private static string GetContinuationIndent(string baseIndent, bool isOrdered) =>
233190
baseIndent + new string(' ', isOrdered ? 3 : 2);
234191

235-
/// <summary>
236-
/// Renders any block type with proper list continuation indentation
237-
/// </summary>
238192
private static void RenderBlockWithIndentation(LlmMarkdownRenderer renderer, Block block, string baseIndent, bool isOrdered)
239193
{
240194
using var tempWriter = new StringWriter();
@@ -304,13 +258,11 @@ protected override void Write(LlmMarkdownRenderer renderer, QuoteBlock obj)
304258
}
305259
}
306260

307-
/// <summary>
308-
/// Renders thematic breaks as standard markdown horizontal rules
309-
/// </summary>
310261
public class LlmThematicBreakRenderer : MarkdownObjectRenderer<LlmMarkdownRenderer, ThematicBreakBlock>
311262
{
312263
protected override void Write(LlmMarkdownRenderer renderer, ThematicBreakBlock obj)
313264
{
265+
renderer.EnsureBlockSpacing();
314266
renderer.Writer.WriteLine("---");
315267
renderer.EnsureLine();
316268
}
@@ -447,9 +399,6 @@ private static int[] CalculateColumnWidths(LlmMarkdownRenderer renderer, Table t
447399
}
448400
}
449401

450-
/// <summary>
451-
/// Renders MyST directives as structured comments for LLM understanding with improved visual separation
452-
/// </summary>
453402
public class LlmDirectiveRenderer : MarkdownObjectRenderer<LlmMarkdownRenderer, DirectiveBlock>
454403
{
455404
protected override void Write(LlmMarkdownRenderer renderer, DirectiveBlock obj)
@@ -459,7 +408,6 @@ protected override void Write(LlmMarkdownRenderer renderer, DirectiveBlock obj)
459408
case ImageBlock imageBlock:
460409
WriteImageBlock(renderer, imageBlock);
461410
return;
462-
// Special handling for include directives
463411
case IncludeBlock includeBlock:
464412
WriteIncludeBlock(renderer, includeBlock);
465413
return;
@@ -509,18 +457,11 @@ private static void WriteImageBlock(LlmMarkdownRenderer renderer, ImageBlock ima
509457
renderer.EnsureLine();
510458
}
511459

512-
/// <summary>
513-
/// Renders definition lists as structured XML for better LLM comprehension
514-
/// </summary>
515-
/// <summary>
516-
/// Renders include directives by fetching and rendering the included content
517-
/// </summary>
518460
private void WriteIncludeBlock(LlmMarkdownRenderer renderer, IncludeBlock block)
519461
{
520-
// If the include wasn't found or path is null, just write a comment
521462
if (!block.Found || block.IncludePath is null)
522463
{
523-
renderer.Writer.WriteLine($"<!-- INCLUDE ERROR: File not found or invalid path -->");
464+
renderer.BuildContext.Collector.EmitError(block.IncludePath ?? string.Empty, "File not found or invalid path");
524465
return;
525466
}
526467

@@ -530,7 +471,7 @@ private void WriteIncludeBlock(LlmMarkdownRenderer renderer, IncludeBlock block)
530471
var snippet = block.Build.ReadFileSystem.FileInfo.New(block.IncludePath);
531472
if (!snippet.Exists)
532473
{
533-
renderer.Writer.WriteLine($"<!-- INCLUDE ERROR: File does not exist: {block.IncludePath} -->");
474+
renderer.BuildContext.Collector.EmitError(block.IncludePath ?? string.Empty, "File not found or invalid path");
534475
return;
535476
}
536477

@@ -540,62 +481,40 @@ private void WriteIncludeBlock(LlmMarkdownRenderer renderer, IncludeBlock block)
540481
// For literal includes, output the content as a code block
541482
// Read the file content
542483
var content = block.Build.ReadFileSystem.File.ReadAllText(block.IncludePath);
543-
544-
// Add language if specified
545-
renderer.Writer.Write("```");
484+
renderer.Write("```");
546485
if (!string.IsNullOrEmpty(block.Language))
547-
{
548-
renderer.Writer.Write(block.Language);
549-
}
550-
486+
renderer.Write(block.Language);
551487
renderer.WriteLine();
552-
// Add an extra newline after the opening code block marker
553-
renderer.Writer.WriteLine();
554-
555-
// Write the content
556-
renderer.Writer.Write(content);
557-
558-
// Close the code block
559-
renderer.Writer.WriteLine();
560-
renderer.Writer.WriteLine("```");
561-
562-
// Add multiple line breaks after code blocks for better readability
488+
renderer.Write(content);
489+
renderer.WriteLine();
490+
renderer.WriteLine("```");
563491
}
564492
else
565493
{
566-
// For regular includes, parse as markdown and render
567494
try
568495
{
569496
var parentPath = block.Context.MarkdownParentPath ?? block.Context.MarkdownSourcePath;
570-
var document = MarkdownParser.ParseSnippetAsync(block.Build, block.Context, snippet, parentPath, block.Context.YamlFrontMatter, default)
497+
var document = MarkdownParser.ParseSnippetAsync(block.Build, block.Context, snippet, parentPath, block.Context.YamlFrontMatter, Cancel.None)
571498
.GetAwaiter().GetResult();
572-
573-
// Use the same renderer to render the included content
574499
_ = renderer.Render(document);
575500
}
576501
catch (Exception ex)
577502
{
578-
renderer.Writer.WriteLine($"<!-- INCLUDE ERROR: Failed to parse included content: {ex.Message} -->");
503+
renderer.BuildContext.Collector.EmitError(block.IncludePath ?? string.Empty, "Failed to parse included content", ex);
579504
}
580505
}
581506

582507
renderer.EnsureLine();
583508
}
584509

585-
/// <summary>
586-
/// Writes children with the specified indentation applied to each line
587-
/// </summary>
588510
private static void WriteChildrenWithIndentation(LlmMarkdownRenderer renderer, Block container, string indent)
589511
{
590-
// Simple approach: capture output and manually add indentation
512+
// Capture output and manually add indentation
591513
using var sw = new StringWriter();
592514
var originalWriter = renderer.Writer;
593515
renderer.Writer = sw;
594-
595516
try
596517
{
597-
// Render children to our temporary writer
598-
599518
switch (container)
600519
{
601520
case ContainerBlock containerBlock:
@@ -605,30 +524,15 @@ private static void WriteChildrenWithIndentation(LlmMarkdownRenderer renderer, B
605524
renderer.WriteLeafInline(leafBlock);
606525
break;
607526
}
608-
609-
610-
// Get the output and add indentation to each non-empty line
611527
var content = sw.ToString();
612528
if (string.IsNullOrEmpty(content))
613529
return;
614530
var reader = new StringReader(content);
615531
while (reader.ReadLine() is { } line)
616-
{
617-
if (string.IsNullOrWhiteSpace(line))
618-
{
619-
// Empty line - write as-is
620-
originalWriter.WriteLine();
621-
}
622-
else
623-
{
624-
// Non-empty line - add indentation
625-
originalWriter.WriteLine(indent + line);
626-
}
627-
}
532+
originalWriter.WriteLine(string.IsNullOrWhiteSpace(line) ? string.Empty : indent + line);
628533
}
629534
finally
630535
{
631-
// Restore original writer
632536
renderer.Writer = originalWriter;
633537
}
634538
}

src/tooling/docs-assembler/Building/AssemblerBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public async Task BuildAllAsync(FrozenDictionary<string, AssemblerDocumentationS
5555

5656
var markdownExporters = new List<IMarkdownExporter>(3);
5757
if (exportOptions.Contains(ExportOption.LLMText))
58-
markdownExporters.Add(new LlmMarkdownExporter()); // Use new advanced LLM renderer
58+
markdownExporters.Add(new LlmMarkdownExporter());
5959
if (exportOptions.Contains(ExportOption.Elasticsearch) && esExporter is { })
6060
markdownExporters.Add(esExporter);
6161
var noopBuild = !exportOptions.Contains(ExportOption.Html);

0 commit comments

Comments
 (0)