///|
/// Renders a snapshot and highlights every audit finding in a self-contained SVG.
pub fn render_audit_svg(
snapshot : LayoutSnapshot,
report : AuditReport,
) -> String {
let mut output = "\n"
}
///|
fn report_summary(report : AuditReport) -> String {
"status=" +
(if report.passed { "PASS" } else { "FAIL" }) +
" overlaps=" +
report.overlap_pairs.to_string() +
" crossings=" +
report.edge_crossings.to_string() +
" out_of_bounds=" +
report.out_of_bounds.to_string()
}
///|
fn edge_points_for_svg(
snapshot : LayoutSnapshot,
edge : Edge,
) -> (PositionedNode, PositionedNode)? {
match
(
find_node_for_svg(snapshot.nodes, edge.source),
find_node_for_svg(snapshot.nodes, edge.target),
) {
(Some(source), Some(target)) => Some((source, target))
_ => None
}
}
///|
fn find_node_for_svg(
nodes : Array[PositionedNode],
id : String,
) -> PositionedNode? {
for node in nodes {
if node.id == id {
return Some(node)
}
}
None
}
///|
fn edge_key_for_svg(edge : Edge) -> String {
edge.source + "->" + edge.target
}
///|
fn edge_has_violation(report : AuditReport, key : String) -> Bool {
for violation in report.violations {
if violation.kind == "edge_crossing" &&
(violation.first == key || violation.second == key) {
return true
}
}
false
}
///|
fn node_has_violation(report : AuditReport, id : String) -> Bool {
for violation in report.violations {
if violation.first == id || violation.second == id {
return true
}
}
false
}
///|
fn node_left_for_svg(node : PositionedNode) -> Int {
node.x - node.width / 2
}
///|
fn node_top_for_svg(node : PositionedNode) -> Int {
node.y - node.height / 2
}
///|
fn escape_xml(input : String) -> String {
input
.replace_all(old="&", new="&")
.replace_all(old="<", new="<")
.replace_all(old=">", new=">")
.replace_all(old="\"", new=""")
}