| |
doc.push_to_body(&error);
|
| |
}
|
| |
|
| - |
for cmd in self.commands.iter() {
|
| - |
cmd.format(&mut doc);
|
| - |
}
|
| - |
|
| |
if self.timeout {
|
| |
let timeout = Element::new(Tag::P).with_text("Last command timed out");
|
| |
doc.push_to_body(&timeout);
|
| |
}
|
| |
|
| + |
let mut toc = ToC::default();
|
| + |
let mut body = Element::new(Tag::Div);
|
| + |
for cmd in self.commands.iter() {
|
| + |
cmd.format(&mut body, &mut toc);
|
| + |
}
|
| + |
|
| + |
doc.push_to_body(&toc.as_html());
|
| + |
doc.push_to_body(&body);
|
| + |
|
| |
let html = format!("{}", doc);
|
| |
std::fs::write(&self.filename, html.as_bytes())
|
| |
.map_err(|e| RunLogError::Write(self.filename.clone(), e))?;
|
| |
self.argv.as_slice().join(" ")
|
| |
}
|
| |
|
| - |
fn format(&self, doc: &mut Document) {
|
| - |
doc.push_to_body(
|
| - |
&Element::new(Tag::H2)
|
| - |
.with_text("Run: ")
|
| - |
.with_child(Element::new(Tag::Code).with_text(&self.command())),
|
| + |
fn format(&self, body: &mut Element, toc: &mut ToC) {
|
| + |
body.push_child(
|
| + |
&toc.push(
|
| + |
Element::new(Tag::Span)
|
| + |
.with_text("Run: ")
|
| + |
.with_child(Element::new(Tag::Code).with_text(&self.command())),
|
| + |
),
|
| |
);
|
| |
|
| - |
doc.push_to_body(&Element::new(Tag::P).with_text("Command arguments:"));
|
| + |
body.push_child(&Element::new(Tag::P).with_text("Command arguments:"));
|
| |
let mut ul = Element::new(Tag::Ul);
|
| |
for arg in self.argv.iter() {
|
| |
ul.push_child(
|
| |
.with_child(Element::new(Tag::Code).with_text(&format!("{:?}", arg))),
|
| |
);
|
| |
}
|
| - |
doc.push_to_body(&ul);
|
| + |
body.push_child(&ul);
|
| |
|
| - |
doc.push_to_body(
|
| + |
body.push_child(
|
| |
&Element::new(Tag::P)
|
| |
.with_text("In directory: ")
|
| |
.with_child(Element::new(Tag::Code).with_text(&format!("{}", self.cwd.display()))),
|
| |
);
|
| |
|
| - |
doc.push_to_body(&Element::new(Tag::P).with_text(&format!("Exit code: {}", self.exit)));
|
| + |
body.push_child(&Element::new(Tag::P).with_text(&format!("Exit code: {}", self.exit)));
|
| |
|
| - |
self.output(doc, "Stdout:", &self.stdout);
|
| - |
self.output(doc, "Stderr:", &self.stderr);
|
| + |
self.output(body, "Stdout:", &self.stdout);
|
| + |
self.output(body, "Stderr:", &self.stderr);
|
| |
}
|
| |
|
| - |
fn output(&self, doc: &mut Document, stream: &str, data: &[u8]) {
|
| + |
fn output(&self, body: &mut Element, stream: &str, data: &[u8]) {
|
| |
if !data.is_empty() {
|
| - |
doc.push_to_body(&Element::new(Tag::P).with_text(stream));
|
| - |
doc.push_to_body(
|
| - |
&Element::new(Tag::P).with_child(
|
| - |
Element::new(Tag::Blockquote).with_child(
|
| - |
Element::new(Tag::Pre).with_text(&String::from_utf8_lossy(data)),
|
| - |
),
|
| - |
),
|
| + |
body.push_child(&Element::new(Tag::P).with_text(stream));
|
| + |
body.push_child(
|
| + |
&Element::new(Tag::Blockquote)
|
| + |
.with_child(Element::new(Tag::Pre).with_text(&String::from_utf8_lossy(data))),
|
| + |
);
|
| + |
}
|
| + |
}
|
| + |
}
|
| + |
|
| + |
#[derive(Debug, Default)]
|
| + |
struct ToC {
|
| + |
counter: usize,
|
| + |
headings: Vec<(String, Element)>,
|
| + |
}
|
| + |
|
| + |
impl ToC {
|
| + |
fn push(&mut self, content: Element) -> Element {
|
| + |
self.counter += 1;
|
| + |
let anchor = format!("h{}", self.counter);
|
| + |
self.headings.push((anchor.clone(), content.clone()));
|
| + |
Element::new(Tag::H2)
|
| + |
.with_attribute("id", &format!("h{}", self.counter))
|
| + |
.with_child(content)
|
| + |
}
|
| + |
|
| + |
fn as_html(&self) -> Element {
|
| + |
let mut toc =
|
| + |
Element::new(Tag::Div).with_child(Element::new(Tag::H2).with_text("Table of contents"));
|
| + |
let mut list = Element::new(Tag::Ul);
|
| + |
for (anchor, content) in self.headings.iter() {
|
| + |
let entry = Element::new(Tag::Li).with_child(
|
| + |
Element::new(Tag::A)
|
| + |
.with_attribute("href", &format!("#{anchor}"))
|
| + |
.with_child(content.clone()),
|
| |
);
|
| + |
list.push_child(&entry);
|
| |
}
|
| + |
toc.push_child(&list);
|
| + |
toc
|
| |
}
|
| |
}
|
| |
|