06b9de0132c8653afc3c2d91cbc386c2f3967e72 lrnassar Tue Apr 28 12:05:20 2026 -0700 QA cleanup of /docs/ landing page and staticPage.lua writer. refs #36894 docs/index.md: fix /docs/contacts.html -> /contacts.html (was 404), correct "Hubs Basics" -> "Hub Basics", drop stray "?" in fragment-only URLs (/cgi-bin/hgHubConnect?#hubDeveloper etc.), convert section headings to sentence case per GB convention, rewrite tutorial-table descriptions in a consistent imperative voice, and replace the fragmented "Checked using our hub development tools" bullet with "Validate your hub with our hub development tools". docs/staticPage.lua: extend Link() to add target="_blank" rel="noopener" on http(s):// absolute URLs, and stop emitting empty title='' on every link. Modernize Table() output to drop deprecated HTML4 attributes: -> , and align="left|right|center" on / replaced with style="text-align: ..." (omitted for the default left alignment). Renames html_align() -> html_align_style() to reflect the new return value. diff --git docs/staticPage.lua docs/staticPage.lua index 3fc86255de3..615beda2a3d 100644 --- docs/staticPage.lua +++ docs/staticPage.lua @@ -208,43 +208,51 @@ return '' .. s .. '' end function obfuscate(s) -- obfuscate the email address a la Hiram's encodeEmail.pl local refs = {} for i = 1, string.len(s) do local ascCode = string.byte(s, i) local ref = "&#" .. tostring(ascCode) table.insert(refs, ref) end return table.concat(refs, "") end function Link(s, src, tit, attr) + local extra = "" if string.sub(src, 1, 7)=="mailto:" then src = "mailto:" .. obfuscate(string.sub(src, 7), 7) -- assume that the link label is an email address if it contains an @ character if string.match(s, "%@")~=nil then s = obfuscate(s) end else + -- absolute URLs open in a new tab; rel="noopener" prevents tabnabbing + if string.match(src, "^https?://") then + extra = " target='_blank' rel='noopener'" + end src = escape(src, true) tit = escape(tit, true) end + if tit and tit ~= "" then + extra = extra .. " title='" .. tit .. "'" + end - return "" .. s .. "" + return "" .. s .. "" end function Image(s, src, tit, attr) return "" .. escape(s,true) .. "" end function Code(s, attr) return "" .. escape(s) .. "" end function InlineMath(s) return "\\(" .. escape(s) .. "\\)" @@ -358,89 +366,87 @@ return "
    \n" .. table.concat(buffer, "\n") .. "\n
" end -- Revisit association list STackValue instance. function DefinitionList(items) local buffer = {} for _,item in pairs(items) do for k, v in pairs(item) do table.insert(buffer,"
" .. k .. "
\n
" .. table.concat(v,"
\n
") .. "
") end end return "
\n" .. table.concat(buffer, "\n") .. "\n
" end --- Convert pandoc alignment to something HTML can use. --- align is AlignLeft, AlignRight, AlignCenter, or AlignDefault. -function html_align(align) - if align == 'AlignLeft' then - return 'left' - elseif align == 'AlignRight' then - return 'right' +-- Convert pandoc alignment into a style attribute fragment for HTML5. +-- align is AlignLeft, AlignRight, AlignCenter, or AlignDefault. Left is the +-- default cell alignment, so emit nothing in that case. +function html_align_style(align) + if align == 'AlignRight' then + return ' style="text-align: right"' elseif align == 'AlignCenter' then - return 'center' + return ' style="text-align: center"' else - return 'left' + return '' end end function CaptionedImage(src, tit, caption) return '
\n\n' .. '

' .. caption .. '

\n
' end -- Caption is a string, aligns is an array of strings, -- widths is an array of floats, headers is an array of -- strings, rows is an array of arrays of strings. function Table(caption, aligns, widths, headers, rows) local buffer = {} local function add(s) table.insert(buffer, s) end add("") if caption ~= "" then add("") end if widths and widths[1] ~= 0 then for _, w in pairs(widths) do - add('') + add('') end end local header_row = {} local empty_header = true for i, h in pairs(headers) do - local align = html_align(aligns[i]) - table.insert(header_row,'') + table.insert(header_row,'' .. h .. '') empty_header = empty_header and h == "" end if empty_header then head = "" else add('') for _,h in pairs(header_row) do add(h) end add('') end local class = "even" for _, row in pairs(rows) do class = (class == "even" and "odd") or "even" add('') for i,c in pairs(row) do - add('') + add('' .. c .. '') end add('') end add('
" .. caption .. "
' .. h .. '
' .. c .. '
') return table.concat(buffer,'\n') end function RawInline(format, str) if format == "html" then return str else --- not sure what to do here for PDF or ebook output... --- return str end end