fix(html): match vimwiki export output for headings, code fences, tags, anchors (#6)
Exported HTML diverged from upstream vimwiki's :VimwikiAll2HTML in ways that break custom templates' CSS/JS and deep-links. Bring the renderer to parity on the structural differences reported in #6: 1. Headings — restore vimwiki's structure: a wrapping `<div id="{hierarchical}">` (parent anchors joined by `-`), `class="header"`, and an in-heading `<a href="#{hierarchical}">` self-link. The flat `id` stays on the heading element so intra-page TOC / `#anchor` links keep resolving. Ancestor path is tracked while walking top-level headings. 2. Code fences — emit vimwiki's `<pre {raw-attrs}>` (the verbatim text after `{{{`, e.g. `<pre python>`) instead of `<pre><code class="language-X">`, so highlighters wired for vimwiki output apply. The fence text is now preserved verbatim through the lexer/AST (PreformattedNode.attrs). 3. Inline tag ids — drop the `tag-` prefix (`id="wiki"`, not `id="tag-wiki"`). Also fixes a real inconsistency: the LSP validated `[[Page#wiki]]` as resolvable while the HTML emitted `id="tag-wiki"`, so the exported link was broken. 4. Same-page anchors — `[[#Section]]` resolves to `index.html#Section` (current page filename + fragment), matching vimwiki, rather than a bare `#Section`. Also ship vimwiki's stock style.css verbatim as the default stylesheet (was a ~7-line minimal one) so exports look identical out of the box and the `.header`/`.tag`/`.toc`/`done*` classes are styled. Centered headings and the `<div class="toc">` Contents wrapper keep their existing form. Tests updated across core + lsp to the new output; added coverage for hierarchical ids, raw fence attrs, bare tag ids, and the same-page anchor filename. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -179,7 +179,9 @@ fn preformatted_block_parses_language() {
|
||||
#[test]
|
||||
fn preformatted_block_parses_attrs() {
|
||||
let lexed = lex("{{{rust class=\"hl\" key=val\nx\n}}}\n");
|
||||
let PreformattedOpen { language, attrs } = &lexed[0] else {
|
||||
let PreformattedOpen {
|
||||
language, attrs, raw, ..
|
||||
} = &lexed[0] else {
|
||||
panic!("expected PreformattedOpen");
|
||||
};
|
||||
assert_eq!(language.as_deref(), Some("rust"));
|
||||
@@ -187,6 +189,8 @@ fn preformatted_block_parses_attrs() {
|
||||
expected.insert("class".into(), "hl".into());
|
||||
expected.insert("key".into(), "val".into());
|
||||
assert_eq!(attrs, &expected);
|
||||
// The verbatim fence text is preserved for the HTML renderer.
|
||||
assert_eq!(raw, "rust class=\"hl\" key=val");
|
||||
}
|
||||
|
||||
// ===== Math block =====
|
||||
|
||||
Reference in New Issue
Block a user