Line data Source code
1 : //! The renderer specs of the visualizations of `@vis` tags.
2 : //!
3 : //! - `vegalite_generator`: the Vega-Lite JSON of an analyzed visualization
4 : //! - `markdown`: the Markdown row template compiled into a document tree, parsed with
5 : //! pulldown-cmark
6 : //!
7 : //! The functions are pure, callers cache the results.
8 :
9 : mod markdown;
10 : mod vegalite_generator;
11 :
12 : pub use markdown::{
13 : compile_markdown_spec, compile_markdown_template, pack_markdown_spec, MarkdownDocument, MarkdownNode,
14 : };
15 : pub use vegalite_generator::generate_vegalite_spec;
16 :
17 : use dashql_core::analyzer::{AnalyzedScript, VisualizationSpec};
18 : use dashql_parser::parser::context::resolve_text_span;
19 :
20 : /// The text of a node (`input.substr(span.offset(), span.length())`)
21 13 : fn node_text(script: &AnalyzedScript, node_id: u32) -> &[u8] {
22 13 : let scanned = &script.parsed.scanned;
23 13 : let span = resolve_text_span(&scanned.text, &scanned.symbols, *script.parsed.nodes[node_id as usize].symbol_span());
24 13 : let text = scanned.text.as_bytes();
25 13 : let begin = (span.offset as usize).min(text.len());
26 13 : let end = (span.offset as usize + span.length as usize).min(text.len());
27 13 : &text[begin..end]
28 13 : }
29 :
30 : /// The renderer-specific packing of a visualization (the vegalite and markdown branches of
31 : /// `AnalyzedScript::Pack`)
32 : #[allow(clippy::type_complexity)]
33 3 : pub fn pack_visualization(
34 3 : script: &AnalyzedScript,
35 3 : spec: &VisualizationSpec,
36 3 : ) -> (
37 3 : Option<String>,
38 3 : Option<Box<dashql_buffers::visualization::MarkdownSpecT>>,
39 3 : ) {
40 : use dashql_buffers::visualization::MarkdownSpec;
41 3 : let renderer = spec.renderer.as_deref();
42 3 : let vegalite = (renderer == Some("vegalite"))
43 3 : .then(|| generate_vegalite_spec(spec, script))
44 3 : .filter(|json| !json.is_empty());
45 3 : let markdown =
46 3 : (renderer == Some("markdown")).then(|| compile_markdown_spec(spec)).flatten().map(|doc| {
47 1 : let mut builder = flatbuffers::FlatBufferBuilder::new();
48 1 : let packed = pack_markdown_spec(&mut builder, &doc);
49 1 : builder.finish(packed, None);
50 1 : Box::new(flatbuffers::root::<MarkdownSpec>(builder.finished_data()).unwrap().unpack())
51 1 : });
52 3 : (vegalite, markdown)
53 3 : }
54 :
55 : #[cfg(test)]
56 : mod tests;
|