1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
// To generate SVG from this example:
//
// cargo run --example example | ansisvg --colorscheme "Builtin Solarized Dark" --fontname "Source Code Pro" --fontsize 18 > example.svg
use codesnake::{Block, CodeWidth, Label, LineIndex};
use core::fmt::Display;
use yansi::{Color, Paint};
const SRC: &str = r#"(defun factorial (n) (if (zerop n) 1
(* n (factorial (1- n)))))"#;
fn style(html: bool, d: &impl Display, color: Color) -> String {
if html {
let mut color = format!("{color:?}");
color.make_ascii_lowercase();
format!("<span class={color}>{d}</span>",)
} else {
d.fg(color).to_string()
}
}
fn main() {
/* to find the byte positions in this example:
for ci in SRC.char_indices() {
println!("{ci:?}");
}
*/
let html = std::env::args().skip(1).any(|arg| arg == "--html");
let idx = LineIndex::new(SRC);
let color = |color| move |s| style(html, &s, color);
let labels = [
Label::new(1..6).with_style(color(Color::Red)),
Label::new(7..16)
.with_text("this function ...")
.with_style(color(Color::Green)),
Label::new(21..70)
.with_text("... is defined by this")
.with_style(color(Color::Blue)),
Label::new(71..71)
.with_text("(and here is EOF)")
.with_style(color(Color::Yellow)),
];
let block = Block::new(&idx, labels).unwrap().map_code(|s| {
let s = s.replace('\t', " ");
let w = unicode_width::UnicodeWidthStr::width(&*s);
CodeWidth::new(s, core::cmp::max(w, 1))
});
println!(
"{}{}",
block.prologue(),
style(html, &"[fac.lisp]", Color::Red)
);
print!("{block}");
println!("{}", block.epilogue());
}
|