feat(config): P3 config batch — group 4 (valid_html_tags, emoji, color_tag_template)

- valid_html_tags: HTML export now passes the allowlisted inline tags through
  verbatim (b/i/sub/sup/kbd/div/center/strong/em/...) and escapes the rest,
  via a render-time tag-aware escaper (write_escaped_allowing/match_allowed_tag)
  — mirroring upstream's s:safe_html_line regex rather than a parser change.
  `span` is always allowed so colour spans render.
- emoji_enable: render-time `:alias:` -> glyph substitution (curated common
  set), default on; with_emoji builder + substitute_emoji/emoji_for.
- color_tag_template: :VimwikiColorize now wraps via a configurable template
  (g:nuwiki_color_tag_template / setup color_tag_template), splitting on
  __CONTENT__ with __COLORFG__ -> colour; both clients. Colour spans render in
  export via the valid_html_tags span passthrough. Default template reproduces
  the prior `<span style="color:NAME">` output (harness colorize tests green).

Renderer gets with_valid_html_tags + with_emoji; export.rs wires both from
HtmlConfig. Tests: valid_html_tags passthrough + escape, emoji on/off
(html_export.rs). Full rust suite + both harnesses green (Neovim 307,
Vim 301/18/21); clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 12:30:38 +00:00
parent dcb5d89c0c
commit 5d1ac09245
5 changed files with 256 additions and 5 deletions
+11 -2
View File
@@ -1213,8 +1213,17 @@ function M.colorize(color, visual)
end
local row = vim.api.nvim_win_get_cursor(0)[1]
local line = vim.api.nvim_get_current_line()
local open_tag = string.format('<span style="color:%s">', color)
local close_tag = '</span>'
-- vimwiki `color_tag_template`: split on __CONTENT__ into open/close, with
-- __COLORFG__ replaced by the colour. Configurable via the setup option /
-- g:nuwiki_color_tag_template.
local tpl = (require('nuwiki.config').options or {}).color_tag_template
or vim.g.nuwiki_color_tag_template
or '<span style="color:__COLORFG__">__CONTENT__</span>'
tpl = tpl:gsub('__COLORFG__', color)
local open_tag, close_tag = tpl:match('^(.*)__CONTENT__(.*)$')
if not open_tag then
open_tag, close_tag = string.format('<span style="color:%s">', color), '</span>'
end
if visual then
local sl, sc, el, ec = visual_selection_range()
if sl and sl == el then