Compare commits
3 Commits
f859437560
...
70f240a656
Author | SHA1 | Date |
---|---|---|
xfnw | 70f240a656 | |
xfnw | 9b7c421568 | |
xfnw | 4bc535da57 |
83
src/html.rs
83
src/html.rs
|
@ -7,7 +7,10 @@ use slugify::slugify;
|
|||
use std::cmp::min;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Handler(pub HtmlExport);
|
||||
pub struct Handler {
|
||||
pub exp: HtmlExport,
|
||||
pub numdir: usize,
|
||||
}
|
||||
|
||||
impl Traverser for Handler {
|
||||
fn event(&mut self, event: Event, ctx: &mut TraversalContext) {
|
||||
|
@ -28,13 +31,13 @@ impl Traverser for Handler {
|
|||
slugify!(&txt)
|
||||
};
|
||||
|
||||
self.0.push_str(format!(
|
||||
self.exp.push_str(format!(
|
||||
r##"<h{} id="{1}"><a role=none href="#{1}">{2}</a> "##,
|
||||
lvl, id, lead
|
||||
));
|
||||
|
||||
if let Some(keyword) = headline.todo_keyword() {
|
||||
self.0.push_str(match headline.todo_type() {
|
||||
self.exp.push_str(match headline.todo_type() {
|
||||
Some(TodoType::Todo) => {
|
||||
format!("<span class=todo>{}</span> ", HtmlEscape(keyword.as_ref()))
|
||||
}
|
||||
|
@ -49,7 +52,7 @@ impl Traverser for Handler {
|
|||
self.element(e, ctx);
|
||||
}
|
||||
|
||||
self.0.push_str(format!("</h{}>", lvl));
|
||||
self.exp.push_str(format!("</h{}>", lvl));
|
||||
}
|
||||
// why does the default HtmlExport output keywords with literally
|
||||
// zero formatting? no idea! let's instead not output them at all.
|
||||
|
@ -75,51 +78,83 @@ impl Traverser for Handler {
|
|||
|
||||
if link.is_image() {
|
||||
if let Some(Some(caption)) = link.caption().map(|c| c.value()) {
|
||||
self.0.push_str(format!(
|
||||
self.exp.push_str(format!(
|
||||
r#"<img src="{}" alt="{}">"#,
|
||||
HtmlEscape(&path),
|
||||
HtmlEscape(caption.trim())
|
||||
));
|
||||
} else {
|
||||
self.0
|
||||
self.exp
|
||||
.push_str(format!("<img src=\"{}\">", HtmlEscape(&path)));
|
||||
}
|
||||
return ctx.skip();
|
||||
}
|
||||
|
||||
self.0
|
||||
self.exp
|
||||
.push_str(format!("<a href=\"{}\">", HtmlEscape(&path)));
|
||||
|
||||
if !link.has_description() {
|
||||
self.0.push_str(format!("{}</a>", HtmlEscape(&path)));
|
||||
self.exp.push_str(format!("{}</a>", HtmlEscape(&path)));
|
||||
ctx.skip();
|
||||
}
|
||||
}
|
||||
Event::Enter(Container::SpecialBlock(block)) => {
|
||||
if let Some(Some(name)) = block.syntax().first_child().map(|n| {
|
||||
n.children_with_tokens()
|
||||
.filter_map(|t| t.into_token())
|
||||
.nth(1)
|
||||
}) {
|
||||
self.0
|
||||
.push_str(format!("<div class=\"{}\">", HtmlEscape(&name.text())));
|
||||
if let Some(mut par) = block
|
||||
.syntax()
|
||||
.first_child()
|
||||
.map(|n| n.children_with_tokens().filter_map(|t| t.into_token()))
|
||||
{
|
||||
if let Some(name) = par.nth(1) {
|
||||
let name = name.text();
|
||||
|
||||
// strip off some exterior formatting
|
||||
for child in block.syntax().children() {
|
||||
for sub in child.children() {
|
||||
for e in sub.children_with_tokens() {
|
||||
self.element(e, ctx);
|
||||
self.exp
|
||||
.push_str(format!("<div class=\"{}\">", HtmlEscape(&name)));
|
||||
|
||||
if name.eq_ignore_ascii_case("chat") {
|
||||
if let Some(usr) = par.next() {
|
||||
let usr = usr.text().trim();
|
||||
if !usr.is_empty() {
|
||||
self.exp.push_str(
|
||||
"<img class=chat-head aria-hidden=true width=42 src=\"",
|
||||
);
|
||||
for _ in 1..self.numdir {
|
||||
self.exp.push_str("../");
|
||||
}
|
||||
self.exp.push_str(format!(
|
||||
r#"faces/{}.png"><span class=chat-nick aria-label="{1} says"><{1}></span> "#,
|
||||
slugify!(usr), HtmlEscape(usr.rsplit_once('/').map_or(usr, |u| u.0))
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.0.push_str("</div>");
|
||||
self.output_block_children(block, ctx);
|
||||
|
||||
self.exp.push_str("</div>");
|
||||
}
|
||||
}
|
||||
ctx.skip();
|
||||
}
|
||||
Event::Enter(Container::Subscript(_)) => self.0.push_str("_"),
|
||||
Event::Enter(Container::Subscript(_)) => self.exp.push_str("_"),
|
||||
Event::Leave(Container::Subscript(_)) => (),
|
||||
_ => self.0.event(event, ctx),
|
||||
_ => self.exp.event(event, ctx),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
/// output children while stripping off some exterior formatting
|
||||
fn output_block_children(
|
||||
&mut self,
|
||||
block: orgize::ast::SpecialBlock,
|
||||
ctx: &mut TraversalContext,
|
||||
) {
|
||||
for child in block.syntax().children() {
|
||||
for sub in child.children() {
|
||||
for e in sub.children_with_tokens() {
|
||||
self.element(e, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -88,14 +88,19 @@ fn generate(
|
|||
ctime.get(&full_path).ok_or("missing creation time")?;
|
||||
let modified = mtime.get(&full_path).ok_or("missing modification time")?.0;
|
||||
|
||||
let mut html_export = html::Handler::default();
|
||||
let numdir = full_path.iter().count();
|
||||
|
||||
let mut html_export = html::Handler {
|
||||
numdir,
|
||||
..Default::default()
|
||||
};
|
||||
res.traverse(&mut html_export);
|
||||
|
||||
let old_page = modified.seconds() - year_ago < 0;
|
||||
|
||||
let template = PageHtml {
|
||||
title: title.clone(),
|
||||
body: html_export.0.finish(),
|
||||
body: html_export.exp.finish(),
|
||||
commit: short_id,
|
||||
author,
|
||||
created: DateTime::from_timestamp(created.seconds(), 0)
|
||||
|
@ -104,7 +109,7 @@ fn generate(
|
|||
modified: DateTime::from_timestamp(modified.seconds(), 0)
|
||||
.ok_or("broken modification date")?
|
||||
.naive_utc(),
|
||||
numdir: full_path.iter().count(),
|
||||
numdir,
|
||||
old_page,
|
||||
};
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@ code, kbd, pre, textarea {
|
|||
color: #eee;
|
||||
}
|
||||
|
||||
code, kbd, pre, .flex div, .box, textarea {
|
||||
code, kbd, pre, .flex div, .box, .chat, textarea {
|
||||
background: #222;
|
||||
}
|
||||
|
||||
.box, .alert, .warning, .fixme {
|
||||
.box, .alert, .warning, .chat, .fixme, .FIXME {
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
@ -143,6 +143,15 @@ img {
|
|||
float: left;
|
||||
}
|
||||
|
||||
.chat-head {
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.chat-nick {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
body {
|
||||
background: white;
|
||||
|
@ -167,7 +176,7 @@ img {
|
|||
code, kbd, pre, textarea {
|
||||
color: #111;
|
||||
}
|
||||
code, kbd, pre, .flex div, .box, textarea {
|
||||
code, kbd, pre, .flex div, .box, .chat, textarea {
|
||||
background: #ddd;
|
||||
}
|
||||
blockquote {
|
||||
|
|
Loading…
Reference in New Issue