diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Give readme headings anchors like GitHub's
A readme's links to its own sections, as in a table of contents, had
nothing on the page to land on.
Diffstat (limited to 'custom/extensions/about-render.lua')
| -rw-r--r-- | custom/extensions/about-render.lua | 37 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 file changed, 36 insertions, 1 deletion
diff --git a/custom/extensions/about-render.lua b/custom/extensions/about-render.lua index 73b1336..6ee790b 100644 --- a/custom/extensions/about-render.lua +++ b/custom/extensions/about-render.lua @@ -32,6 +32,10 @@ local max_depth = 24 local filename, tree_base, tree_query, chunks = "", "", "", {} +-- How often each heading anchor has been handed out. The ids already on the +-- page around the readme start at one, so no heading takes them. +local id_counts = {} + -- Lua patterns backtrack, so "%s+$" costs the square of a run of spaces in -- the middle of a line. Finding each end directly stays linear. @@ -204,6 +208,34 @@ local function shows_something(lines) return false end +local function plain_text(nodes, parts) + for _, node in ipairs(nodes) do + if node.kind == "text" or node.kind == "code" then + parts[#parts + 1] = node.text + elseif node.kids then + plain_text(node.kids, parts) + end + end + return parts +end + +-- Gives a heading the anchor GitHub would, so a readme's links to its own +-- sections work. That is its text in lower case, with punctuation dropped +-- and each space a hyphen, and a count added to a repeat. Bytes past ASCII +-- stay, keeping the letters of other scripts. +local function emit_id(nodes) + local base = table.concat(plain_text(nodes, {})):lower() + :gsub("[^%w_%- \128-\255]", ""):gsub(" ", "-") + if base == "" then + return + end + local count = id_counts[base] or 0 + id_counts[base] = count + 1 + html(" id='") + html_attr(count > 0 and base .. "-" .. count or base) + html("'") +end + local function emit_lines(lines) for i, line in ipairs(lines) do if i > 1 then @@ -219,7 +251,9 @@ emit_blocks = function(blocks) for _, block in ipairs(blocks) do local kind = block.kind if kind == "heading" then - html("<h" .. block.level .. ">") + html("<h" .. block.level) + emit_id(block.kids) + html(">") emit_inline(block.kids) html("</h" .. block.level .. ">") elseif kind == "hr" then @@ -778,6 +812,7 @@ function filter_open(name, base, query) tree_base = base or "" tree_query = query or "" chunks = {} + id_counts = { cgit = 1, header = 1, about = 1 } end function filter_write(str) |
