use std::path::Path;
use zenith_core::{Diagnostic, Document, Node, TextNode, TextSpan};
pub(crate) fn resolve_text_sources(
doc: &mut Document,
project_dir: Option<&Path>,
diagnostics: &mut Vec<Diagnostic>,
) {
for page in &mut doc.body.pages {
resolve_in_nodes(&mut page.children, project_dir, diagnostics);
}
}
fn resolve_in_nodes(
nodes: &mut [Node],
project_dir: Option<&Path>,
diagnostics: &mut Vec<Diagnostic>,
) {
for node in nodes.iter_mut() {
match node {
Node::Text(text) => {
if let Some(rel_path) = text.src.clone() {
resolve_one(text, &rel_path, project_dir, diagnostics);
}
}
Node::Frame(f) => {
resolve_in_nodes(&mut f.children, project_dir, diagnostics);
}
Node::Group(g) => {
resolve_in_nodes(&mut g.children, project_dir, diagnostics);
}
Node::Table(t) => {
for row in &mut t.rows {
for cell in &mut row.cells {
resolve_in_nodes(&mut cell.children, project_dir, diagnostics);
}
}
}
Node::Rect(_)
| Node::Ellipse(_)
| Node::Line(_)
| Node::Code(_)
| Node::Image(_)
| Node::Polygon(_)
| Node::Polyline(_)
| Node::Instance(_)
| Node::Field(_)
| Node::Toc(_)
| Node::Footnote(_)
| Node::Shape(_)
| Node::Connector(_)
| Node::Pattern(_)
| Node::Chart(_)
| Node::Light(_)
| Node::Mesh(_)
| Node::Unknown(_) => {}
}
}
}
fn resolve_one(
text: &mut TextNode,
rel_path: &str,
project_dir: Option<&Path>,
diagnostics: &mut Vec<Diagnostic>,
) {
let dir = match project_dir {
Some(d) => d,
None => {
diagnostics.push(Diagnostic::error(
"text.src_missing",
format!(
"text node '{}': src=\"{}\" cannot be resolved — no project directory available",
text.id, rel_path
),
text.source_span,
Some(text.id.clone()),
));
return;
}
};
let full_path = dir.join(rel_path);
match std::fs::read_to_string(&full_path) {
Ok(contents) => {
text.spans = vec![TextSpan {
text: contents,
fill: None,
font_weight: None,
italic: None,
underline: None,
strikethrough: None,
vertical_align: None,
footnote_ref: None,
data_ref: None,
data_format: None,
highlight: None,
code: None,
link: None,
}];
}
Err(e) => {
diagnostics.push(Diagnostic::error(
"text.src_missing",
format!(
"text node '{}': src=\"{}\" could not be read from '{}': {}",
text.id,
rel_path,
full_path.display(),
e
),
text.source_span,
Some(text.id.clone()),
));
}
}
}