commit c1fa3c7c377b6e507782ef33d3d2b307931633d6
parent 29c5559ce10c41092ff39ab5d43fdcb17d8fe64b
Author: Yochem van Rosmalen <git@yochem.nl>
Date: Sun, 24 Aug 2025 00:04:52 +0200
feat(gen_help_html): generate helptags.json, helptag.html #35442
Problem:
No way to know the html page with the docs of a tag when you only have
the tag name.
Solution:
Generate a helptags.json that maps tags to their locations.
Generate a helptag.html page that redirects to the HTML page of the given tag.
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Diffstat:
1 file changed, 72 insertions(+), 0 deletions(-)
diff --git a/src/gen/gen_help_html.lua b/src/gen/gen_help_html.lua
@@ -1025,6 +1025,76 @@ local function gen_one(fname, text, to_fname, old, commit, parser_path)
return html, stats
end
+--- Generates an HTML page that does a client-side redirect to the tag given by the "?tag=…"
+--- querystring parameter. The page gets tags from the "helptags.json" file.
+local function gen_helptag_html(fname)
+ local html = [[
+ <!doctype html>
+ <html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Redirecting…</title>
+ <script type="module">
+ async function do_redirect() {
+ const errorDiv = document.getElementById('error-message');
+ try {
+ const params = new URLSearchParams(window.location.search)
+ const tag = params.get('tag')
+ if (!tag) {
+ throw new Error('No tag parameter')
+ }
+
+ // helptags.json lives next to helptag.html
+ const res = await fetch('./helptags.json')
+ if (!res.ok) {
+ throw new Error('helptags.json not found')
+ }
+
+ const tagmap = await res.json()
+ if (!tagmap[tag]) {
+ throw new Error('helptag not found: "' + tag + '"')
+ }
+
+ window.location.href = tagmap[tag]
+ } catch (err) {
+ console.error(err)
+ if (errorDiv) {
+ errorDiv.textContent = err.message
+ }
+ // Optionally, redirect to index after showing error
+ // setTimeout(() => window.location.href = './index.html', 3000)
+ }
+ }
+
+ do_redirect()
+ </script>
+ </head>
+ <body>
+ <p>Redirecting…</p>
+ <div id="error-message" style="margin-top:1em; font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;"></div>
+ </body>
+ </html>
+ ]]
+ tofile(fname, html)
+end
+
+--- Generates a JSON map of tags to URL-encoded `filename#anchor` locations.
+---
+---@param fname string
+local function gen_helptags_json(fname)
+ assert(tagmap, '`tagmap` not generated yet')
+ local t = {} ---@type table<string, string>
+ for tag, f in pairs(tagmap) do
+ -- "foo.txt"
+ local helpfile = vim.fs.basename(f)
+ -- "foo.html"
+ local htmlpage = assert(get_helppage(helpfile))
+ -- "foo.html#tag"
+ t[tag] = ('%s#%s'):format(htmlpage, url_encode(tag))
+ end
+ tofile(fname, vim.json.encode(t))
+end
+
local function gen_css(fname)
local css = [[
:root {
@@ -1301,6 +1371,8 @@ function M.gen(help_dir, to_dir, include, commit, parser_path)
print(('output dir: %s\n\n'):format(to_dir))
vim.fn.mkdir(to_dir, 'p')
gen_css(('%s/help.css'):format(to_dir))
+ gen_helptags_json(('%s/helptags.json'):format(to_dir))
+ gen_helptag_html(('%s/helptag.html'):format(to_dir))
for _, f in ipairs(helpfiles) do
-- "foo.txt"