Browse Source

punknative generator: nav index, per-form arg tables, terminal-black backdrop, integer row pitch

Improvements from user review of the punk::ansi trial page:

- command index <nav> at page top (doctools-style jump list); hook to
  display @package info above it when specs carry package_info (guarded -
  key absent in older punk::args spec dicts)
- multiform commands: punk::args::usage renders all form synopses but only
  the default form arg table (terminal UX expects i -form N) - the page now
  adds a per-form ARG TABLE for each form that has arguments, trimmed at the
  table-header separator so the command/description/synopsis panel is not
  repeated per form (renderspace lines are colour-self-contained, so slicing
  at a line boundary is safe); argument-less forms are skipped
- pre backdrop is now true black (page body stays dark grey):
  overtype::renderspace overlay output emits explicit SGR 40 and example
  helpers treat default background as the terminal backdrop - on black they
  blend as in a terminal (proper fix = default-colour semantics, goal)
- row pitch line-height:17px (integer, just under the 17.85px inline
  background height at font-size 15.36px) - the fractional 1.15em pitch put
  row boundaries at fractional positions and showed periodic hairline gaps
  through solid-bg runs
- explicit package require punk::lib (tstr placeholder resolution uses
  punk::lib::undent; previously loaded only by transitive luck when usage
  ran before get_spec)

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 1 day ago
parent
commit
5df5f65b4f
  1. 116
      src/scriptapps/tools/punkargs_punknative.tcl

116
src/scriptapps/tools/punkargs_punknative.tcl

@ -48,6 +48,7 @@ foreach libdir [list [file normalize $project_root/src/bootsupport/lib] [file no
if {$libdir ni $::auto_path} {lappend ::auto_path $libdir}
}
package require punk::args
package require punk::lib ;#punk::args::lib::tstr placeholder resolution uses punk::lib::undent
package require punk::ansi
lassign $argv pkgname outdir
@ -102,7 +103,12 @@ namespace eval ansi2html {
#666666 #f14c4c #23d18b #f5f543 #3b8eea #d670d6 #29b8db #ffffff
}
variable default_fg "#d4d4d4"
variable default_bg "#1e1e1e"
#terminal backdrop for rendered blocks: BLACK. overtype::renderspace
#overlay output uses explicit SGR 40 (black bg) and art/example helpers
#treat 'default background' as the terminal's - on a black pre they blend
#exactly as in a black terminal (a grey pre showed contrasting black bars
#inside example blocks). The page body stays lighter for contrast.
variable default_bg "#000000"
proc color256 {n} {
variable pal16
@ -346,8 +352,11 @@ set fontstack "'Cascadia Mono','Cascadia Code','DejaVu Sans Mono','Noto Sans Mon
if {$fontface ne ""} {
set fontstack "'punkdoc-mono',$fontstack"
}
append html "body {background:$ansi2html::default_bg; color:$ansi2html::default_fg; font-family:$fontstack;}\n"
append html "h1,h2 {font-family:inherit; color:#e5e510;}\n"
append html "body {background:#1e1e1e; color:$ansi2html::default_fg; font-family:$fontstack;}\n"
append html "h1,h2,h3 {font-family:inherit; color:#e5e510;}\n"
append html "nav.cmdindex {background:#000; padding:8px 12px; display:inline-block;}\n"
append html "nav.cmdindex a {color:#29b8db; text-decoration:none; display:inline-block; margin-right:1.5em;}\n"
append html "nav.cmdindex a:hover {text-decoration:underline;}\n"
#IMPORTANT: pre needs its own font-family - the UA stylesheet's
#'pre {font-family:monospace}' overrides inheritance from body, so without
#this the pre renders in the browser's default mono font regardless of the
@ -355,13 +364,84 @@ append html "h1,h2 {font-family:inherit; color:#e5e510;}\n"
#punkdoc-mono cell geometry (see fontprep/README.md): advance is exactly
#0.5859375em - font-size 15.36px gives an integer 9px cell width (fractional
#advances round differently at styled-span boundaries -> vertical seams
#through block/border glyphs). If the font stack falls back past
#punkdoc-mono this exactness is lost but text-only content tolerates it.
append html "pre.punkterm {font-family:$fontstack; line-height:1.15; font-size:15.36px; overflow-x:auto; padding:8px; background:$ansi2html::default_bg; font-variant-ligatures:none;}\n"
#through block/border glyphs). Row pitch: browsers size inline BACKGROUNDS
#to the font's hhea content area = 1.1621em = 17.85px here; a fractional
#pitch (1.15em = 17.664px) put row boundaries at fractional positions and
#showed periodic hairline gaps through solid-bg runs (~every 2 lines).
#line-height:17px = integer pitch just under the bg height, so adjacent
#rows' backgrounds overlap ~0.85px - sealed at any zoom/dpi (cost: bg rows
#overpaint <1px of the row above's descenders - imperceptible in tables).
#If the font stack falls back past punkdoc-mono this exactness is lost but
#text-only content tolerates it.
append html "pre.punkterm {font-family:$fontstack; line-height:17px; font-size:15.36px; overflow-x:auto; padding:8px; background:$ansi2html::default_bg; font-variant-ligatures:none;}\n"
append html "hr {border:0; border-top:1px solid #444;}\n"
append html "</style></head><body>\n"
append html "<h1>$pkgname $pkgversion</h1>\n"
append html "<p>Command reference generated from punk::args definitions (terminal-faithful rendering).</p>\n"
#module/package-level info when @package directives are registered (none in
#older module versions - the hook is here for when dev modules surface them)
set package_notes [list]
foreach id $cmd_ids {
set spec [punk::args::get_spec $id]
#package_info key absent in older punk::args spec dicts (pre-@package)
if {![dict exists $spec package_info]} {break}
set pinfo [dict get $spec package_info]
if {[llength $pinfo] && $pinfo ni $package_notes} {
lappend package_notes $pinfo
}
}
foreach pinfo $package_notes {
append html "<p>package: [ansi2html::html_escape [punk::ansi::ansistrip $pinfo]]</p>\n"
}
#command index navigation (doctools-style jump list)
append html "<nav class=\"cmdindex\">\n"
foreach id $cmd_ids {
set cmdname [string trimleft $id :]
set esc [ansi2html::html_escape $cmdname]
append html "<a href=\"#$esc\">$esc</a>\n"
}
append html "</nav>\n"
#helper: one converted usage block.
#-trim 1: keep only the Arg table (from its header separator down) - used for
#per-form blocks so they don't repeat the whole command/description/synopsis
#panel and drown the per-form differences (renderspace output lines are
#colour-self-contained, so slicing at a line boundary is safe)
proc usage_block {id args} {
global boxmap
set trim 0
set idx [lsearch -exact $args -trim]
if {$idx >= 0} {
set trim [lindex $args $idx+1]
set args [lreplace $args $idx $idx+1]
}
if {[catch {punk::args::usage {*}$args $id} u]} {
return "<p>(no usage rendering: [ansi2html::html_escape $u])</p>\n"
}
if {$trim} {
set lines [split $u \n]
set argidx -1
set i 0
foreach ln $lines {
if {[string match "Arg *" [punk::ansi::ansistrip $ln]]} {
set argidx $i
break
}
incr i
}
if {$argidx > 0} {
#include the separator line above the Arg header as the top border
set u [join [lrange $lines $argidx-1 end] \n]
}
}
if {$boxmap eq "light"} {
set u [ansi2html::to_lightbox $u]
}
return "<pre class=\"punkterm\">[ansi2html::convert $u]</pre>\n"
}
foreach id $cmd_ids {
set cmdname [string trimleft $id :]
append html "<hr><h2 id=\"[ansi2html::html_escape $cmdname]\">$cmdname</h2>\n"
@ -369,14 +449,24 @@ foreach id $cmd_ids {
if {$aliastarget ne ""} {
append html "<p>Takes the same arguments as <b>[ansi2html::html_escape [string trimleft $aliastarget :]]</b> (shared argument definition).</p>\n"
}
if {[catch {punk::args::usage $id} u]} {
append html "<p>(no usage rendering: [ansi2html::html_escape $u])</p>\n"
continue
}
if {$boxmap eq "light"} {
set u [ansi2html::to_lightbox $u]
#the default usage table shows description + all form synopses, but for
#multiform commands its Arg table covers only the default form - render
#an additional per-form ARG TABLE (trimmed - no repeated header panel)
#for each form that has arguments (mirrors 'i -form N <cmd>').
append html [usage_block $id]
set spec [punk::args::get_spec $id]
set formnames [dict get $spec form_names]
if {[llength $formnames] > 1} {
foreach formname $formnames {
set form [dict get $spec FORMS $formname]
if {![dict size [dict get $form ARG_INFO]]} {
#form takes no arguments - the synopsis line says it all
continue
}
append html "<h3>form: [ansi2html::html_escape $formname]</h3>\n"
append html [usage_block $id -form $formname -trim 1]
}
}
append html "<pre class=\"punkterm\">[ansi2html::convert $u]</pre>\n"
}
append html "</body></html>\n"
set fd [open [file join $outdir $pkgfile.html] w]

Loading…
Cancel
Save