Skip to main content

custom_rendering/
custom_rendering.rs

1//! Custom rendering options example.
2//!
3//! This example shows how to customize the output format using TextRenderOptions,
4//! particularly useful for disabling terminal hyperlinks in snapshot tests.
5
6use quarto_error_reporting::{DiagnosticMessageBuilder, TextRenderOptions};
7use quarto_source_map::{SourceContext, SourceInfo};
8
9fn main() {
10    println!("=== Example 1: Default rendering (with hyperlinks) ===\n");
11
12    let mut ctx = SourceContext::new();
13    let file_id = ctx.add_file(
14        "document.qmd".to_string(),
15        Some("# My Document\n\nSome content here.\n".to_string()),
16    );
17
18    let location = SourceInfo::original(file_id, 15, 27);
19
20    let error = DiagnosticMessageBuilder::error("Parse error")
21        .with_code("Q-2-100")
22        .with_location(location)
23        .problem("Invalid markdown syntax")
24        .add_hint("Check the markdown formatting")
25        .build();
26
27    // Default rendering includes OSC 8 hyperlinks for file paths
28    let default_text = error.to_text(Some(&ctx));
29    println!("{}", default_text);
30
31    println!("\n=== Example 2: Rendering without hyperlinks (for tests) ===\n");
32
33    // Disable hyperlinks - useful for snapshot testing where absolute paths
34    // would cause differences between machines
35    let options = TextRenderOptions {
36        enable_hyperlinks: false,
37    };
38
39    let no_hyperlink_text = error.to_text_with_options(Some(&ctx), &options);
40    println!("{}", no_hyperlink_text);
41
42    println!("\n=== Example 3: Comparing outputs ===\n");
43
44    // Show the difference in output
45    println!("With hyperlinks enabled:");
46    println!("  Length: {} bytes", default_text.len());
47    println!(
48        "  Contains OSC 8 codes: {}",
49        default_text.contains("\x1b]8;")
50    );
51
52    println!("\nWith hyperlinks disabled:");
53    println!("  Length: {} bytes", no_hyperlink_text.len());
54    println!(
55        "  Contains OSC 8 codes: {}",
56        no_hyperlink_text.contains("\x1b]8;")
57    );
58
59    println!("\n=== Example 4: JSON output (no hyperlinks) ===\n");
60
61    let json = error.to_json();
62    println!("{}", serde_json::to_string_pretty(&json).unwrap());
63
64    println!("\n=== Example 5: Multiple diagnostics with custom rendering ===\n");
65
66    let error2 = DiagnosticMessageBuilder::error("Type mismatch")
67        .with_code("Q-1-15")
68        .problem("Expected string, found number")
69        .add_detail("Value: 42")
70        .add_detail("Expected type: string")
71        .build();
72
73    let error3 = DiagnosticMessageBuilder::error("Missing field")
74        .with_code("Q-1-20")
75        .problem("Required field 'author' not found")
76        .add_hint("Add an 'author' field to your configuration")
77        .build();
78
79    let errors = [error, error2, error3];
80
81    // Render all with consistent options
82    let no_hyperlinks = TextRenderOptions {
83        enable_hyperlinks: false,
84    };
85
86    for (i, err) in errors.iter().enumerate() {
87        println!("Error {}:", i + 1);
88        println!("{}", err.to_text_with_options(Some(&ctx), &no_hyperlinks));
89        println!();
90    }
91}