use std::collections::HashMap; use std::ops::Range; use std::rc::Rc; use std::sync::Once; use crate::parser::util::Property; use crate::parser::util::PropertyMapError; use crate::parser::util::PropertyParser; use ariadne::Fmt; use ariadne::Label; use ariadne::Report; use ariadne::ReportKind; use crypto::digest::Digest; use crypto::sha2::Sha512; use graphviz_rust::cmd::Format; use graphviz_rust::cmd::Layout; use graphviz_rust::exec_dot; use mlua::Function; use mlua::Lua; use regex::Captures; use regex::Regex; use crate::cache::cache::Cached; use crate::cache::cache::CachedError; use crate::compiler::compiler::Compiler; use crate::compiler::compiler::Target; use crate::document::document::Document; use crate::document::element::ElemKind; use crate::document::element::Element; use crate::parser::parser::Parser; use crate::parser::rule::RegexRule; use crate::parser::source::Source; use crate::parser::source::Token; use crate::parser::util; #[derive(Debug)] struct Graphviz { pub location: Token, pub dot: String, pub layout: Layout, pub caption: Option, } fn layout_from_str(value: &str) -> Result { match value { "dot" => Ok(Layout::Dot), "neato" => Ok(Layout::Neato), "fdp" => Ok(Layout::Fdp), "sfdp" => Ok(Layout::Sfdp), "circo" => Ok(Layout::Circo), "twopi" => Ok(Layout::Twopi), "osage" => Ok(Layout::Asage), // typo in graphviz_rust ? "patchwork" => Ok(Layout::Patchwork), _ => Err(format!("Unknown layout: {value}")), } } impl Graphviz { /// Renders dot to svg fn dot_to_svg(&self) -> Result { print!("Rendering Graphviz `{}`... ", self.dot); let svg = match exec_dot( self.dot.clone(), vec![self.layout.into(), Format::Svg.into()], ) { Ok(svg) => { let out = String::from_utf8_lossy(svg.as_slice()); let split_at = out.find("