#!/bin/tclsh
#
# Run this TCL script to generate syntax bubble diagrams from
# text descriptions.
#
# This version generates a pure HTML table based version with
# no graphics, all in one file named "all-text.html". It may
# be useful to people wanting text search or screen reader
# support.
source [file join [file dirname [info script]] bubble-generator-data.tcl]
# used for curves
set rad "4px"
set rad1 "5px"
# used for bubble text (<= (2 x rad)+2)
set font1 "9px"
# used for arrows (~ 3 x rad)
set font2 "12px"
# used for everything else (~ font1+5)
set font3 "14px"
# |
set c9474 "
"
# -|
set c9488 ""
# |-
set c9484 ""
# |_
set c9492 ""
# _|
set c9496 ""
#-(- top left
set c9581 ""
#-)- top right
set c9582 ""
#-|-
set c9516 ""
#( bot left
set c9584 ""
# ) bot right
set c9583 ""
# |-
set c9500 ""
# -|
set c9508 ""
#->
set rarr ""
# <-
set larr ""
# ---
set hr ""
# Draw a bubble containing $txt.
#
proc draw_bubble {txt} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
if {$txt=="nil"} {
return [list 1 ""]
} elseif {$txt=="bullet"} {
return [list 1 ""]
}
if {[regexp {^/[a-z]} $txt]} {
set txt [string range $txt 1 end]
set istoken 1
} elseif {[regexp {^[a-z]} $txt]} {
set istoken 0
} else {
set istoken 1
}
set href " $txt "
set txt " $txt "
if {$istoken} {
return [list 1 ""]
} else {
return [list 1 ""]
}
return [list 0 ""]
}
# Draw a sequence of terms from left to write. Each element of $lx
# descripts a single term.
#
proc draw_line {lx} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
set n [llength $lx]
set h 1
set content ""
set i 0
foreach term $lx {
incr i
set rc [draw_diagram $term]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
if { $th > $h } { set h $th }
if {$i != $n} {
set content "$content$tcontent | $rarr | "
} else {
set content "$content$tcontent | "
}
}
set content ""
return [list $h $content]
}
# Draw a sequence of terms from right to left.
#
proc draw_backwards_line {lx} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
set n [llength $lx]
set h 1
if {$n < 1} {
set content "$hr | "
} {
set content ""
set i 0
foreach term $lx {
incr i
set rc [draw_diagram $term 1]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
if { $th > $h } { set h $th }
if {$i != $n} {
set content "$larr | $tcontent | $content"
} else {
set content "$tcontent | $content"
}
}
}
set content ""
return [list $h $content]
}
# Draw a sequence of terms from top to bottom.
#
proc draw_stack {indent lx} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
set n [llength $lx]
set h 0
set content ""
set i 0
foreach term $lx {
set rc [draw_diagram $term 1]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
set h [ expr { $h + $th } ]
set v [ expr { $th - 1 } ]
set vert [string repeat "$c9474 |
" $v]
incr i
if {$i == 1} {
set down ""
set up ""
set content "$content
$hr | $hr | $tcontent | $rarr | $down | $up |
"
} elseif {$i == $n} {
set content "$content$c9492 | $rarr | $tcontent | $hr | $rarr | $c9496 |
"
} else {
set down ""
set up ""
set content "$content$c9492 | $rarr | $tcontent | $rarr | $down | $up |
"
}
if {$i != $n} {
incr h
set content "$content$c9484 | $larr | $hr | $larr | $c9496 | $c9474 |
"
}
}
set content "$content
"
return [list $h $content]
}
proc draw_loop {forward back} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
set h 0
set content ""
set rc [draw_diagram $forward 1]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
set v [ expr { $th - 1 } ]
set vert [string repeat "$c9474 |
" $v]
set up "$c9581"
set down "$c9582"
if { $v > 0 } {
set up ""
set down ""
}
set h [ expr { $h + $th } ]
set content "$content
$up | $rarr | $tcontent | $rarr | $down |
"
set rc [draw_backwards_line $back]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
set h [ expr { $h + $th } ]
set content "$content$c9584 | $larr | $tcontent | $larr | $c9583 |
"
set content "$content
"
return [list $h $content]
}
proc draw_toploop {forward back} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
set h 0
set content ""
set rc [draw_diagram $forward 1]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
set v [ expr { $th - 1 } ]
set vert [string repeat "$c9474 |
" $v]
set up "$c9581"
set down "$c9582"
if { $v > 0 } {
set up ""
set down ""
}
set h [ expr { $h + $th } ]
set content "$content
$up | $rarr | $tcontent | $rarr | $down |
"
set rc [draw_backwards_line $back]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
set h [ expr { $h + $th } ]
set content "$content$c9584 | $larr | $tcontent | $larr | $c9583 |
"
set content "$content
"
return [list $h $content]
}
proc draw_or {lx} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
set n [llength $lx]
set h 0
if {$n < 1} {
set content "$hr |
"
} else {
set content ""
set i 0
foreach term $lx {
set rc [draw_diagram $term 1]
set th [lindex $rc 0]
set tcontent [lindex $rc 1]
set v [ expr { $th - 1 } ]
set vert [string repeat "$c9474 |
" $v]
incr i
if {$i == 1} {
set beg "
$c9582 |
"
set end "
$c9581 |
"
} elseif {$i == $n} {
set beg "
$c9584 |
"
set end "
$c9583 |
"
set vert ""
} else {
set beg "
$c9500 |
"
set end "
$c9508 |
"
}
set h [ expr { $h + $th } ]
set content "$content
| $rarr | $tcontent | $rarr | |
"
}
}
set content ""
return [list $h $content]
}
proc draw_diagram {spec {draw_hr 0}} {
global c9474 c9488 c9484 c9492 c9496 c9581 c9582 c9516 c9584 c9583 c9500 c9508 rarr larr hr
set n [llength $spec]
set cmd [lindex $spec 0]
if {$n==1} {
set rc [draw_bubble $spec]
} elseif {$n==0} {
set rc [draw_bubble nil]
} elseif {$cmd=="line"} {
set rc [draw_line [lrange $spec 1 end]]
} elseif {$cmd=="stack"} {
set rc [draw_stack 0 [lrange $spec 1 end]]
} elseif {$cmd=="indentstack"} {
set rc [draw_stack $::HSEP [lrange $spec 1 end]]
} elseif {$cmd=="loop"} {
set rc [draw_loop [lindex $spec 1] [lindex $spec 2]]
} elseif {$cmd=="toploop"} {
set rc [draw_toploop [lindex $spec 1] [lindex $spec 2]]
} elseif {$cmd=="or"} {
set rc [draw_or [lrange $spec 1 end]]
} elseif {$cmd=="opt"} {
set args [lrange $spec 1 end]
if {[llength $args]==1} {
set rc [draw_or [list nil [lindex $args 0]]]
} else {
set rc [draw_or [list nil "line $args"]]
}
} elseif {$cmd=="optx"} {
set args [lrange $spec 1 end]
if {[llength $args]==1} {
set rc [draw_or [list [lindex $args 0] nil]]
} else {
set rc [draw_or [list "line $args" nil]]
}
} elseif {$cmd=="tailbranch"} {
# set rc [draw_tail_branch [lrange $spec 1 end]]
set rc [draw_or [lrange $spec 1 end]]
} else {
error "unknown operator: $cmd"
}
set h [lindex $rc 0]
set content [lindex $rc 1]
if {$draw_hr} {
set content ""
} {
set content ""
}
return [list $h $content]
}
proc draw_graph {name spec} {
set rc [ draw_diagram "line bullet [list $spec] bullet"]
set h [lindex $rc 0]
set content [lindex $rc 1]
return [list $h $content]
}
set f [open all-text.html w]
puts $f ""
puts $f ""
puts $f ""
puts $f ""
puts $f ""
puts $f ""
foreach {name graph} $all_graphs {
if {$name == "sql-stmt-list" || 1} {
puts $f ""
set rc [draw_graph $name $graph]
set h [lindex $rc 0]
set content [lindex $rc 1]
puts $f "$content"
}
}
puts $f ""
puts $f ""
close $f