fix(export): render vimwiki-compatible HTML for templates, links, and tasks
Stock vimwiki templates and stylesheets rendered broken pages because the
HTML output diverged from vimwiki conventions on three fronts:
- Templates: the renderer only substituted nuwiki's `{{key}}` placeholders,
so vimwiki's `%title%`/`%content%`/`%root_path%`/`%date%`/`%wiki_css%`
passed through literally — dropping the body and breaking asset links.
Both delimiter styles are now recognised; `%wiki_css%` aliases the css var.
- Links: `[[todo.wiki]]` exported to `todo.wiki.html`. render_page_html now
takes the wiki file extension and strips it from wiki/interwiki targets
(via index::strip_wiki_extension) before the `.html` URL is built, matching
in-editor navigation. file:/local: links keep their literal extension.
- Tasks: checkbox items used bespoke `task-*` classes plus an `<input>`,
which double-rendered against vimwiki stylesheets. Emit `done0..done4`
(`[ ] [.] [o] [O] [X]`) and `rejected` (`[-]`) classes with no input — the
stylesheet draws the box.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -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("<ul>"));
|
||||
assert!(out.contains("<input type=\"checkbox\" disabled checked>"));
|
||||
assert!(out.contains("done</li>"));
|
||||
assert!(out.contains("not done</li>"));
|
||||
// vimwiki-compatible: class on the <li>, no <input> (the stylesheet draws it).
|
||||
assert!(out.contains("<li class=\"done4\">done</li>"), "{out}");
|
||||
assert!(out.contains("<li>not done</li>"), "{out}");
|
||||
assert!(!out.contains("<input"), "no input element: {out}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checkbox_states_use_vimwiki_done_classes() {
|
||||
let out = render("- [ ] a\n- [.] b\n- [o] c\n- [O] d\n- [X] e\n- [-] f\n");
|
||||
assert!(out.contains("<li class=\"done0\">a</li>"), "{out}");
|
||||
assert!(out.contains("<li class=\"done1\">b</li>"), "{out}");
|
||||
assert!(out.contains("<li class=\"done2\">c</li>"), "{out}");
|
||||
assert!(out.contains("<li class=\"done3\">d</li>"), "{out}");
|
||||
assert!(out.contains("<li class=\"done4\">e</li>"), "{out}");
|
||||
assert!(out.contains("<li class=\"rejected\">f</li>"), "{out}");
|
||||
assert!(!out.contains("task-"), "no legacy task-* classes: {out}");
|
||||
assert!(!out.contains("<input"), "no input elements: {out}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -284,6 +298,23 @@ fn template_with_missing_title_substitutes_empty_string() {
|
||||
assert!(out.contains("<h1>Heading</h1>"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_substitutes_vimwiki_percent_placeholders() {
|
||||
// Stock vimwiki templates use `%title%` / `%content%` / `%root_path%`
|
||||
// rather than nuwiki's `{{…}}`. Both must resolve.
|
||||
let doc = VimwikiSyntax::new().parse("%title My Page\n= Hello =\n");
|
||||
let renderer = HtmlRenderer::new()
|
||||
.with_template(
|
||||
"<title>%title%</title><link href=\"%root_path%style.css\"><body>%content%</body>",
|
||||
)
|
||||
.with_var("root_path", "../");
|
||||
let out = renderer.render_to_string(&doc).unwrap();
|
||||
assert!(out.contains("<title>My Page</title>"), "title: {out}");
|
||||
assert!(out.contains("<body><h1>Hello</h1>"), "content: {out}");
|
||||
assert!(out.contains("href=\"../style.css\""), "root_path: {out}");
|
||||
assert!(!out.contains('%'), "no placeholder left: {out}");
|
||||
}
|
||||
|
||||
// ===== End-to-end smoke =====
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user