standout_render/template/mod.rs
1//! Two-pass template rendering with style tag processing.
2//!
3//! This module provides the core rendering pipeline that transforms templates
4//! and data into styled terminal output. Templates are processed in two passes:
5//! template engine for logic, then BBParser for style tags.
6//!
7//! ## Template Engines
8//!
9//! Two template engines are available:
10//!
11//! | Engine | Syntax | Features | Use When |
12//! |--------|--------|----------|----------|
13//! | [`MiniJinjaEngine`] | `{{ var }}` | Loops, conditionals, filters, includes | Full template logic needed |
14//! | [`SimpleEngine`] | `{var}` | Variable substitution only | Simple output, smaller binary |
15//!
16//! ### MiniJinja (Default)
17//!
18//! Full-featured Jinja2-compatible engine. File extensions: `.jinja`, `.jinja2`, `.j2`
19//!
20//! ```text
21//! [title]{{ name | upper }}[/title] has {{ count }} items
22//! {% for item in items %}{{ item.name }}{% endfor %}
23//! ```
24//!
25//! ### Simple Engine
26//!
27//! Lightweight format-string style substitution. File extension: `.stpl`
28//!
29//! ```text
30//! [title]{name}[/title] has {count} items
31//! {user.profile.email}
32//! ```
33//!
34//! ## Two-Pass Rendering
35//!
36//! Templates are processed in two distinct passes, which is why style tags use
37//! bracket notation (`[name]...[/name]`) instead of template syntax:
38//!
39//! Pass 1 - Template Engine: Variable substitution (and control flow for MiniJinja).
40//! ```text
41//! Template: [title]{{ name | upper }}[/title] has {{ count }} items
42//! After: [title]WIDGET[/title] has 42 items
43//! ```
44//!
45//! Pass 2 - BBParser: Style tags converted to ANSI codes (or stripped).
46//! ```text
47//! Input: [title]WIDGET[/title] has 42 items
48//! Output: \x1b[1;32mWIDGET\x1b[0m has 42 items
49//! ```
50//!
51//! This separation keeps template logic independent from styling concerns.
52//!
53//! ## Which Render Function?
54//!
55//! Choose based on your needs:
56//!
57//! | Function | Use When |
58//! |----------|----------|
59//! | [`render`] | Simple case, let Standout auto-detect everything |
60//! | [`render_with_output`] | Honoring `--output` flag (Term/Text/Auto) |
61//! | [`render_with_mode`] | Full control over output mode AND color mode |
62//! | [`render_auto`] | CLI with `--output=json` support (skips template for structured modes) |
63//!
64//! The "auto" in [`render_auto`] refers to template-vs-serialization dispatch,
65//! not color detection. Structured modes (JSON, YAML, XML, CSV) serialize data
66//! directly, skipping the template entirely.
67//!
68//! ## Style Tags in Templates
69//!
70//! Use bracket notation for styling (works with both engines):
71//! ```text
72//! [title]{{ name }}[/title] - [muted]{{ description }}[/muted] // MiniJinja
73//! [title]{name}[/title] - [muted]{description}[/muted] // Simple
74//! ```
75//!
76//! Tags can nest, span multiple lines, and contain template logic. Unknown tags
77//! show a `?` marker (`[unknown?]text[/unknown?]`) — use [`validate_template`]
78//! to catch typos at startup or in tests.
79//!
80//! ## Template Registry
81//!
82//! For file-based templates, use [`TemplateRegistry`]:
83//!
84//! ```rust,ignore
85//! let mut registry = TemplateRegistry::new();
86//! registry.add_from_files(walk_template_dir("./templates")?)?;
87//! let content = registry.get_content("config")?;
88//! ```
89//!
90//! Resolution priority: inline templates → embedded (compile-time) → file-based.
91//! Supported extensions: `.jinja`, `.jinja2`, `.j2`, `.stpl`, `.txt` (in priority order).
92//!
93//! ## Key Types
94//!
95//! - [`Renderer`]: Pre-compiled template renderer for repeated rendering
96//! - [`TemplateRegistry`]: Template resolution from multiple sources
97//! - [`TemplateEngine`]: Trait for pluggable template backends
98//! - [`MiniJinjaEngine`]: Full-featured Jinja2 engine (default)
99//! - [`SimpleEngine`]: Lightweight format-string engine
100//! - [`validate_template`]: Check templates for unknown style tags
101//!
102//! ## See Also
103//!
104//! - [`crate::theme`]: Theme and style definitions
105//! - [`crate::tabular`]: Column formatting utilities and template filters
106//! - [`crate::context`]: Context injection for templates
107
108mod engine;
109pub mod filters;
110mod functions;
111pub mod registry;
112mod renderer;
113mod simple;
114
115pub use engine::{register_filters, MiniJinjaEngine, TemplateEngine};
116pub use functions::{
117 render, render_auto, render_auto_with_context, render_auto_with_engine, render_auto_with_spec,
118 render_with_context, render_with_mode, render_with_output, render_with_vars, validate_template,
119};
120pub use registry::{
121 walk_template_dir, RegistryError, ResolvedTemplate, TemplateFile, TemplateRegistry,
122 TEMPLATE_EXTENSIONS,
123};
124pub use renderer::Renderer;
125pub use simple::SimpleEngine;