Skip to main content

max / makeover-webview

Say where each bar landed, on the same terms as a cell chart_html_placed is chart_html_into plus a record of each bar column's offsets. Same reason as cells_html_placed: a bar's markup is a function of its magnitude, so two equal bars are the same bytes and a caller compiling the chart into a template cannot find one by searching for it.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01P8ostB2UmZJGj5WjSHRSot
Author: Max Johnson <me@maxj.phd> · 2026-09-08 19:47 UTC
Signed with PGP, not checked
Commit: 0d2cdc15fc9c6820b2619ffc04f543b37e5486bf
Parent: 4dca141
1 file changed, +32 insertions, -0 deletions
M src/chart.rs +32
@@ -76,6 +76,34 @@
76 76 bars: impl IntoIterator<Item = Bar<'a>>,
77 77 opts: &Emit,
78 78 out: &mut String,
79 + ) {
80 + emit_chart(chart, bars, opts, out, None);
81 + }
82 +
83 + /// A chart, saying where each bar landed.
84 + ///
85 + /// Byte-identical to [`chart_html_into`], and it appends one entry to `placed`
86 + /// per bar, in order: the offsets in `out` between which that bar's whole
87 + /// column was written. See [`crate::list::cells_html_placed`], which exists for
88 + /// the same reason and says it at length: a caller compiling this markup into a
89 + /// template has to know which bytes one bar produced, and the writer is the
90 + /// only source for that which cannot be wrong.
91 + pub fn chart_html_placed<'a>(
92 + chart: &Chart<'_>,
93 + bars: impl IntoIterator<Item = Bar<'a>>,
94 + opts: &Emit,
95 + out: &mut String,
96 + placed: &mut Vec<core::ops::Range<usize>>,
97 + ) {
98 + emit_chart(chart, bars, opts, out, Some(placed));
99 + }
100 +
101 + fn emit_chart<'a>(
102 + chart: &Chart<'_>,
103 + bars: impl IntoIterator<Item = Bar<'a>>,
104 + opts: &Emit,
105 + out: &mut String,
106 + mut placed: Option<&mut Vec<core::ops::Range<usize>>>,
79 107 ) {
80 108 out.push_str("<div class=\"");
81 109 push_class(out, "chart", opts);
@@ -105,7 +133,11 @@
105 133 out.push_str("\">");
106 134
107 135 for bar in bars {
136 + let at = out.len();
108 137 bar_html_into(&bar, opts, out);
138 + if let Some(placed) = placed.as_deref_mut() {
139 + placed.push(at..out.len());
140 + }
109 141 }
110 142
111 143 out.push_str("</div></div>");