feat(html): html_header_numbering section numbering for HTML export
Mirror vimwiki's html_header_numbering / html_header_numbering_sym: top-level headings at or below the start level get a dotted section number (1, 1.1, 1.2, ...) with a configurable trailing symbol. Off by default (level 0). Nested headings in lists/quotes stay unnumbered, matching upstream's document-level-only scan. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,8 @@ fn html_config_defaults_match_vimwiki() {
|
||||
assert!(!c.auto_export);
|
||||
assert!(!c.html_filename_parameterization);
|
||||
assert!(c.exclude_files.is_empty());
|
||||
assert_eq!(c.html_header_numbering, 0); // upstream default: numbering off
|
||||
assert!(c.html_header_numbering_sym.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -270,6 +272,73 @@ fn render_page_html_uses_metadata_date_when_set() {
|
||||
assert!(html.contains("DATE=2025-01-02"), "got: {html}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_page_html_numbers_headers_when_enabled() {
|
||||
let ast = parse("= Intro =\n== Background ==\n== Methods ==\n= Results =\n");
|
||||
let mut c = cfg("/tmp/x");
|
||||
c.html.html_header_numbering = 1; // number from h1
|
||||
c.html.html_header_numbering_sym = ".".into();
|
||||
let html = export::render_page_html(
|
||||
&ast,
|
||||
None,
|
||||
"Home",
|
||||
DiaryDate::from_ymd(2026, 5, 11).unwrap(),
|
||||
&c.html,
|
||||
None,
|
||||
-1,
|
||||
HashMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(html.contains("<h1>1. Intro</h1>"), "got: {html}");
|
||||
assert!(html.contains("<h2>1.1. Background</h2>"), "got: {html}");
|
||||
assert!(html.contains("<h2>1.2. Methods</h2>"), "got: {html}");
|
||||
assert!(html.contains("<h1>2. Results</h1>"), "got: {html}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_page_html_numbering_skips_headers_above_start_level() {
|
||||
let ast = parse("= Title =\n== Section ==\n=== Sub ===\n");
|
||||
let mut c = cfg("/tmp/x");
|
||||
c.html.html_header_numbering = 2; // start at h2; h1 stays unnumbered
|
||||
// empty sym → number followed by a bare space
|
||||
let html = export::render_page_html(
|
||||
&ast,
|
||||
None,
|
||||
"Home",
|
||||
DiaryDate::from_ymd(2026, 5, 11).unwrap(),
|
||||
&c.html,
|
||||
None,
|
||||
-1,
|
||||
HashMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(
|
||||
html.contains("<h1>Title</h1>"),
|
||||
"h1 unnumbered, got: {html}"
|
||||
);
|
||||
assert!(html.contains("<h2>1 Section</h2>"), "got: {html}");
|
||||
assert!(html.contains("<h3>1.1 Sub</h3>"), "got: {html}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_page_html_no_header_numbering_by_default() {
|
||||
let ast = parse("= Intro =\n== Sub ==\n");
|
||||
let c = cfg("/tmp/x");
|
||||
let html = export::render_page_html(
|
||||
&ast,
|
||||
None,
|
||||
"Home",
|
||||
DiaryDate::from_ymd(2026, 5, 11).unwrap(),
|
||||
&c.html,
|
||||
None,
|
||||
-1,
|
||||
HashMap::new(),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(html.contains("<h1>Intro</h1>"), "got: {html}");
|
||||
assert!(html.contains("<h2>Sub</h2>"), "got: {html}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_page_html_root_path_for_nested_pages() {
|
||||
let ast = parse("= D =\n");
|
||||
|
||||
@@ -288,6 +288,9 @@ fn defaults_carry_vimwiki_per_wiki_keys() {
|
||||
assert_eq!(cfg.html.custom_wiki2html, "");
|
||||
assert_eq!(cfg.html.custom_wiki2html_args, "");
|
||||
assert_eq!(cfg.html.base_url, "");
|
||||
// HTML section numbering is off by default (vimwiki's `0`).
|
||||
assert_eq!(cfg.html.html_header_numbering, 0);
|
||||
assert_eq!(cfg.html.html_header_numbering_sym, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -319,6 +322,8 @@ fn raw_wiki_parses_every_new_key() {
|
||||
"custom_wiki2html": "~/bin/my_wiki2html.sh",
|
||||
"custom_wiki2html_args": "--flag",
|
||||
"base_url": "https://example.com/wiki/",
|
||||
"html_header_numbering": 2,
|
||||
"html_header_numbering_sym": ".",
|
||||
}],
|
||||
}));
|
||||
let w = &cfg.wikis[0];
|
||||
@@ -350,6 +355,8 @@ fn raw_wiki_parses_every_new_key() {
|
||||
assert_eq!(w.html.custom_wiki2html, "~/bin/my_wiki2html.sh");
|
||||
assert_eq!(w.html.custom_wiki2html_args, "--flag");
|
||||
assert_eq!(w.html.base_url, "https://example.com/wiki/");
|
||||
assert_eq!(w.html.html_header_numbering, 2);
|
||||
assert_eq!(w.html.html_header_numbering_sym, ".");
|
||||
|
||||
// The parsed keys drive a date-mode, Sunday-start diary calendar:
|
||||
// a weekly note is the week-start date (YYYY-MM-DD), stepping ±7 days.
|
||||
|
||||
Reference in New Issue
Block a user