fix: TOC header class, numbering config, and Lua defaults
CI / cargo fmt --check (push) Successful in 31s
CI / cargo clippy (push) Successful in 31s
CI / cargo test (push) Successful in 36s
Release / build x86_64-unknown-linux-gnu (push) Successful in 53s
Release / build aarch64-unknown-linux-musl (push) Successful in 1m6s
Release / build x86_64-unknown-linux-musl (push) Successful in 1m8s
Release / build aarch64-unknown-linux-gnu (push) Successful in 1m47s
Release / gitea release (push) Successful in 28s
CI / editor keymaps (push) Successful in 1m39s
CI / cargo fmt --check (push) Successful in 31s
CI / cargo clippy (push) Successful in 31s
CI / cargo test (push) Successful in 36s
Release / build x86_64-unknown-linux-gnu (push) Successful in 53s
Release / build aarch64-unknown-linux-musl (push) Successful in 1m6s
Release / build x86_64-unknown-linux-musl (push) Successful in 1m8s
Release / build aarch64-unknown-linux-gnu (push) Successful in 1m47s
Release / gitea release (push) Successful in 28s
CI / editor keymaps (push) Successful in 1m39s
- Add class='toc' to TOC heading in HTML export by detecting the configured toc_header value in render_heading() - Add toc_header field to HtmlRenderer and wire it through render_page_html() - Add toc_header, toc_header_level, html_header_numbering, and html_header_numbering_sym to Lua config defaults so users can discover and set them
This commit is contained in:
@@ -59,6 +59,10 @@ pub struct HtmlRenderer {
|
|||||||
/// vimwiki `html_header_numbering_sym`: a symbol appended after the
|
/// vimwiki `html_header_numbering_sym`: a symbol appended after the
|
||||||
/// section number (e.g. `.` → `1.2. Heading`). Empty by default.
|
/// section number (e.g. `.` → `1.2. Heading`). Empty by default.
|
||||||
header_numbering_sym: String,
|
header_numbering_sym: String,
|
||||||
|
/// vimwiki `toc_header`: the heading text that identifies the TOC
|
||||||
|
/// section. When a heading matches this value (case-insensitive), it
|
||||||
|
/// gets `class="toc"` in HTML export.
|
||||||
|
toc_header: String,
|
||||||
/// vimwiki `valid_html_tags`: inline HTML tag names passed through to
|
/// vimwiki `valid_html_tags`: inline HTML tag names passed through to
|
||||||
/// export verbatim (instead of escaping `<`/`>`). Empty = escape all.
|
/// export verbatim (instead of escaping `<`/`>`). Empty = escape all.
|
||||||
/// `span` is always allowed so colour spans render.
|
/// `span` is always allowed so colour spans render.
|
||||||
@@ -90,6 +94,7 @@ impl HtmlRenderer {
|
|||||||
color_template: "<span style=\"__STYLE__\">__CONTENT__</span>".to_string(),
|
color_template: "<span style=\"__STYLE__\">__CONTENT__</span>".to_string(),
|
||||||
header_numbering: 0,
|
header_numbering: 0,
|
||||||
header_numbering_sym: String::new(),
|
header_numbering_sym: String::new(),
|
||||||
|
toc_header: String::new(),
|
||||||
valid_html_tags: Vec::new(),
|
valid_html_tags: Vec::new(),
|
||||||
emoji_enable: false,
|
emoji_enable: false,
|
||||||
text_ignore_newline: true,
|
text_ignore_newline: true,
|
||||||
@@ -183,6 +188,13 @@ impl HtmlRenderer {
|
|||||||
self.header_numbering_sym = sym.into();
|
self.header_numbering_sym = sym.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the vimwiki TOC heading text. When a heading matches this value
|
||||||
|
/// (case-insensitive) it gets `class="toc"` in HTML export.
|
||||||
|
pub fn with_toc_header(mut self, header: impl Into<String>) -> Self {
|
||||||
|
self.toc_header = header.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Running state for vimwiki-style HTML section numbering
|
/// Running state for vimwiki-style HTML section numbering
|
||||||
@@ -314,15 +326,27 @@ impl HtmlRenderer {
|
|||||||
/// pass `""` for no numbering.
|
/// pass `""` for no numbering.
|
||||||
fn render_heading(&self, n: &HeadingNode, number: &str, w: &mut dyn Write) -> io::Result<()> {
|
fn render_heading(&self, n: &HeadingNode, number: &str, w: &mut dyn Write) -> io::Result<()> {
|
||||||
let level = n.level.clamp(1, 6);
|
let level = n.level.clamp(1, 6);
|
||||||
let class = if n.centered {
|
|
||||||
" class=\"centered\""
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
// `id` is the heading's plain text (vimwiki's anchor scheme), so
|
|
||||||
// `[[Page#Heading]]` and TOC `#Heading` links land here. Matches the
|
|
||||||
// anchor text the LSP validates and the resolver emits.
|
|
||||||
let anchor = crate::ast::inline_text(&n.children);
|
let anchor = crate::ast::inline_text(&n.children);
|
||||||
|
let is_toc = self
|
||||||
|
.toc_header
|
||||||
|
.as_bytes()
|
||||||
|
.iter()
|
||||||
|
.zip(anchor.as_bytes())
|
||||||
|
.all(|(a, b)| a.eq_ignore_ascii_case(b))
|
||||||
|
&& !self.toc_header.is_empty()
|
||||||
|
&& self.toc_header.len() == anchor.len();
|
||||||
|
let mut classes = Vec::new();
|
||||||
|
if is_toc {
|
||||||
|
classes.push("toc");
|
||||||
|
}
|
||||||
|
if n.centered {
|
||||||
|
classes.push("centered");
|
||||||
|
}
|
||||||
|
let class = if classes.is_empty() {
|
||||||
|
String::new()
|
||||||
|
} else {
|
||||||
|
format!(" class=\"{}\"", classes.join(" "))
|
||||||
|
};
|
||||||
write!(w, "<h{level}{class} id=\"")?;
|
write!(w, "<h{level}{class} id=\"")?;
|
||||||
write_escaped(&anchor, w)?;
|
write_escaped(&anchor, w)?;
|
||||||
write!(w, "\">")?;
|
write!(w, "\">")?;
|
||||||
|
|||||||
@@ -176,6 +176,10 @@ pub struct HtmlConfig {
|
|||||||
/// vimwiki `html_header_numbering_sym`: symbol appended after the
|
/// vimwiki `html_header_numbering_sym`: symbol appended after the
|
||||||
/// section number (e.g. `.` → `1.2. Heading`). Empty by default.
|
/// section number (e.g. `.` → `1.2. Heading`). Empty by default.
|
||||||
pub html_header_numbering_sym: String,
|
pub html_header_numbering_sym: String,
|
||||||
|
/// vimwiki `toc_header`: the heading text that identifies the TOC
|
||||||
|
/// section. When a heading matches this value (case-insensitive), it
|
||||||
|
/// gets `class="toc"` in HTML export.
|
||||||
|
pub toc_header: String,
|
||||||
/// vimwiki `rss_name`: filename of the generated RSS feed (default
|
/// vimwiki `rss_name`: filename of the generated RSS feed (default
|
||||||
/// `rss.xml`), relative to `html_path`.
|
/// `rss.xml`), relative to `html_path`.
|
||||||
pub rss_name: String,
|
pub rss_name: String,
|
||||||
@@ -224,6 +228,7 @@ impl Default for HtmlConfig {
|
|||||||
base_url: String::new(),
|
base_url: String::new(),
|
||||||
html_header_numbering: 0,
|
html_header_numbering: 0,
|
||||||
html_header_numbering_sym: String::new(),
|
html_header_numbering_sym: String::new(),
|
||||||
|
toc_header: default_toc_header(),
|
||||||
rss_name: "rss.xml".into(),
|
rss_name: "rss.xml".into(),
|
||||||
rss_max_items: 10,
|
rss_max_items: 10,
|
||||||
valid_html_tags: default_valid_html_tags(),
|
valid_html_tags: default_valid_html_tags(),
|
||||||
@@ -954,6 +959,9 @@ impl From<RawWiki> for WikiConfig {
|
|||||||
if let Some(s) = r.html_header_numbering_sym {
|
if let Some(s) = r.html_header_numbering_sym {
|
||||||
html.html_header_numbering_sym = s;
|
html.html_header_numbering_sym = s;
|
||||||
}
|
}
|
||||||
|
if let Some(ref s) = r.toc_header {
|
||||||
|
html.toc_header = s.clone();
|
||||||
|
}
|
||||||
if let Some(s) = r.rss_name {
|
if let Some(s) = r.rss_name {
|
||||||
html.rss_name = s;
|
html.rss_name = s;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ pub fn render_page_html(
|
|||||||
cfg.html_header_numbering_sym.clone(),
|
cfg.html_header_numbering_sym.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
r = r.with_toc_header(&cfg.toc_header);
|
||||||
if !cfg.valid_html_tags.is_empty() {
|
if !cfg.valid_html_tags.is_empty() {
|
||||||
r = r.with_valid_html_tags(cfg.valid_html_tags.clone());
|
r = r.with_valid_html_tags(cfg.valid_html_tags.clone());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,10 +35,19 @@ M.defaults = {
|
|||||||
-- custom_wiki2html, custom_wiki2html_args, base_url,
|
-- custom_wiki2html, custom_wiki2html_args, base_url,
|
||||||
-- toc_header, toc_header_level, links_header, links_header_level,
|
-- toc_header, toc_header_level, links_header, links_header_level,
|
||||||
-- tags_header, tags_header_level,
|
-- tags_header, tags_header_level,
|
||||||
|
-- html_header_numbering, html_header_numbering_sym,
|
||||||
-- listsyms, listsym_rejected, listsyms_propagate, list_margin,
|
-- listsyms, listsym_rejected, listsyms_propagate, list_margin,
|
||||||
-- links_space_char
|
-- links_space_char
|
||||||
wikis = nil,
|
wikis = nil,
|
||||||
|
|
||||||
|
-- TOC defaults (per-wiki, also accepted as top-level for single-wiki setups)
|
||||||
|
toc_header = 'Contents',
|
||||||
|
toc_header_level = 1,
|
||||||
|
|
||||||
|
-- HTML export defaults (per-wiki, also accepted as top-level for single-wiki setups)
|
||||||
|
html_header_numbering = 0,
|
||||||
|
html_header_numbering_sym = '',
|
||||||
|
|
||||||
-- Per-buffer glue. Each subgroup mirrors vimwiki's
|
-- Per-buffer glue. Each subgroup mirrors vimwiki's
|
||||||
-- `g:vimwiki_key_mappings` shape and can be flipped off
|
-- `g:vimwiki_key_mappings` shape and can be flipped off
|
||||||
-- independently to suppress that group of keymaps.
|
-- independently to suppress that group of keymaps.
|
||||||
|
|||||||
Reference in New Issue
Block a user