diff --git a/crates/nuwiki-core/src/render/html.rs b/crates/nuwiki-core/src/render/html.rs
index 7c404bf..8dafd35 100644
--- a/crates/nuwiki-core/src/render/html.rs
+++ b/crates/nuwiki-core/src/render/html.rs
@@ -11,6 +11,11 @@
//! `{{date}}`, `{{root_path}}`, `{{toc}}`). Order: `{{content}}` is
//! substituted first so a body that happens to contain a literal
//! `{{title}}` isn't itself rewritten in the next pass.
+//!
+//! Both delimiter styles are recognised for every placeholder: nuwiki's
+//! native `{{key}}` and vimwiki's `%key%` (`%title%`, `%content%`,
+//! `%root_path%`, `%date%`, `%wiki_css%`, …). This lets stock vimwiki
+//! templates render unchanged.
use std::collections::HashMap;
use std::io::{self, Write};
@@ -107,14 +112,17 @@ impl Renderer for HtmlRenderer {
let body_str = std::str::from_utf8(&body)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
let title = doc.metadata.title.as_deref().unwrap_or("");
- // Replace `{{content}}` first so its substituted body, which may
- // legitimately contain the literal `{{title}}`, isn't itself
- // rewritten in the next pass.
+ // Substitute `content` before `title` so a body that legitimately
+ // contains a literal title placeholder isn't rewritten. Both the
+ // native `{{key}}` and vimwiki's `%key%` delimiters are accepted so
+ // stock vimwiki templates render unchanged.
let mut out = template.replace("{{content}}", body_str);
+ out = out.replace("%content%", body_str);
out = out.replace("{{title}}", title);
+ out = out.replace("%title%", title);
for (k, v) in &self.vars {
- let needle = format!("{{{{{k}}}}}");
- out = out.replace(&needle, v);
+ out = out.replace(&format!("{{{{{k}}}}}"), v);
+ out = out.replace(&format!("%{k}%"), v);
}
w.write_all(out.as_bytes())?;
} else {
@@ -239,18 +247,20 @@ impl HtmlRenderer {
fn render_list_item(&self, n: &ListItemNode, w: &mut dyn Write) -> io::Result<()> {
match n.checkbox {
Some(state) => {
- let (checked, class) = match state {
- CheckboxState::Empty => ("", "task-empty"),
- CheckboxState::Quarter => ("", "task-quarter"),
- CheckboxState::Half => ("", "task-half"),
- CheckboxState::ThreeQuarters => ("", "task-three-quarters"),
- CheckboxState::Done => (" checked", "task-done"),
- CheckboxState::Rejected => ("", "task-rejected"),
+ // vimwiki-compatible checkbox classes: `[ ]`→done0, `[.]`→done1,
+ // `[o]`→done2, `[O]`→done3, `[X]`→done4, `[-]`→rejected. The
+ // checkbox glyph/progress fill is drawn entirely by the
+ // stylesheet (`li.doneN::before`); vimwiki emits no ``,
+ // so neither do we — an input would double-render against it.
+ let class = match state {
+ CheckboxState::Empty => "done0",
+ CheckboxState::Quarter => "done1",
+ CheckboxState::Half => "done2",
+ CheckboxState::ThreeQuarters => "done3",
+ CheckboxState::Done => "done4",
+ CheckboxState::Rejected => "rejected",
};
- write!(
- w,
- "
"
- )?;
+ write!(w, "
")?;
}
None => w.write_all(b"
")?,
}
diff --git a/crates/nuwiki-core/tests/html_renderer.rs b/crates/nuwiki-core/tests/html_renderer.rs
index 24d23d1..9f9110e 100644
--- a/crates/nuwiki-core/tests/html_renderer.rs
+++ b/crates/nuwiki-core/tests/html_renderer.rs
@@ -112,9 +112,23 @@ fn math_block_emits_div() {
fn unordered_list_with_checkbox() {
let out = render("- [X] done\n- not done\n");
assert!(out.contains("