#!/bin/sh # keylist - list hotkey->actions found in .lht files in a html table # Copyright (C) 2015..2016, 2018 Tibor 'Igor2' Palinkas # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # http://www.repo.hu/projects/librnd AWK=awk export LANG=C need_lht() { echo "lhtflat not found. Please install lihata to run this script. The" >&2 echo "svn extern in src_3rd/ is not enough, this script requires a full" >&2 echo "installation from svn://repo.hu/lihata/trunk" >&2 exit 1 } # make sure lhtflat is installed echo "" | lhtflat || need_lht if test -z "$*" then echo "" echo "$0: Generate a html table from pcb menu lht files." echo "Usage: $0 file1 [file2 [file3 ... [fileN]]]" echo "" exit else cmd="html" while test $# -gt 0 do case "$1" in --html) cmd="html";; --boxed) cmd="boxed";; --lst) cmd="lst";; --dot) cmd="dot"; nodenames=$2; shift 1;; *) res_files="$res_files $1" ;; esac shift 1 done fi extract_from_lht() { lhtflat | $AWK -F '[\t]' -v "fn=$1" ' #data text //main_menu/1::Edit/submenu/11::Edit name of/submenu/1::pin on layout/a Shift Ctrln #data text //main_menu/1::Edit/submenu/11::Edit name of/submenu/1::pin on layout/action ChangeName(Object, Number) { tmp = $3 if ($3 ~ "/a/[0-9]*::$") { # li:a = {} sub("/[0-9]*::$", "", tmp) } parent=tmp sub("/[^/]*$","", parent) node=tmp sub("^.*/","", node) } (($1 == "data") && ($2 == "text")) { # simple text node: accel key if (node == "a") { seq=$0 sub("[^\t]*[\t]*[^\t]*[\t]*[^\t]*[\t]*", "", seq) gsub(" ", "", seq) v = split(tolower(seq), S, "[;]") ktmp = "" for(n = 1; n <= v; n++) { if (S[n] ~ "") split(S[n], K, "") else split(S[n], K, "") if (K[1] != "") { mods = "" if (K[1] ~ "alt") mods = mods "-alt" if (K[1] ~ "ctrl") mods = mods "-ctrl" if (K[1] ~ "shift") mods = mods "-shift" } else mods = "" if (ktmp == "") ktmp = K[2] mods else ktmp = ktmp ";" K[2] mods } if (KEY[parent] == "") KEY[parent] = ktmp else KEY[parent] = KEY[parent] SUBSEP ktmp } # simple text node: action if (node == "action") ACTION[parent] = $4 # list item: action if ($3 ~ "/action/[0-9]+::$") { parent = $3 sub("/action/[^/]*$", "", parent) if (ACTION[parent] != "") ACTION[parent] = ACTION[parent] ";" $4 else ACTION[parent] = $4 } } END { for(n in KEY) { menuname = n sub(".*::", "", menuname) v = split(KEY[n], K, "[" SUBSEP "]") for(i = 1; i <= v; i++) print K[i] "\t" fn "\t" ACTION[n] "\t" menuname } } ' } # convert a "key src action" to a html table gen_html() { $AWK -F '[\t]' ' BEGIN { CLR[0] = "#FFFFFF" CLR[1] = "#DDFFFF" key_combos = 0 } function to_base_key(combo) { sub("-.*", "", combo) return combo } function to_mods(combo) { if (!(combo ~ ".-")) return "" sub("^[^-]*[-]", "", combo) return combo } { k = $1 if (last != k) { LIST[key_combos++] = k # ROWSPAN[to_base_key(k)]++ } ACTION[$2, k] = $3 MENUNAME[$2, k] = $4 HIDS[$2]++ last = k v = split(k, K, ";") p = "" for(n = 1; n <= v; n++) { p = p K[n] ";" if (($2, p) in PREFIX) { err = err "
" $2 ": " k " vs. " p ERR[$2, p]++ ERR[$2, k]++ } } p = k ";" PREFIX[$2, p]++ } function cleanup(s) { gsub("\260", "\\°", s) gsub("\\\\37777777660", "\\°", s) gsub("\\\\057", "/", s) return s } END { q="\"" print "" print "" print "" print "" print "\t" print "\t Key to action bindings " print "" print "" print "" print "" print "" print "

Key to action bindings

" print "" printf("" kv = split(key, K, ";") keystr = "" ind="" for(kn = 1; kn <= kv; kn++) { if (kn > 1) keystr = keystr "
" keystr = keystr ind K[kn] ind = ind " " } print "
key action source") print "" for(n = 0; n < key_combos; n++) { clr_cnt++ key = LIST[n] print "
" cleanup(keystr) " " srcs="" for(h in HIDS) { mn = cleanup(MENUNAME[h, key]) act = cleanup(ACTION[h, key]) if ((act == "") && (mn == "")) act = " " else { gsub(");", "); ", act) if (mn != "") act = "" mn "" "
" act if (srcs == "") srcs = h else srcs = srcs "
" h } print act if ((h, key) in ERR) print "
Error: key prefix collision" } if (srcs == "") scrs = "n/a" print "
", srcs last_base = base } print "
" print err print "" } ' } gen_list() { local n for n in $res_files do extract_from_lht "`basename $n`" < $n done | sort } # load node names and generate a dot drawing of the multikey bindings gen_dot() { $AWK -v "names=$nodenames" ' BEGIN { q="\"" print "digraph keytree {" print "rankdir=LR" print "ranksep=0.2" while((getline < names) == 1) { path=$1 $1="" desc = $0 node(path, desc, "shape=box") } close(names) FS="[\t]" } function arrow_(curr) { if (!(curr in ARROW_SEEN)) { print curr ARROW_SEEN[curr]=1 } } function arrow(path ,n,v,P,last,curr) { sub("^[/;_]", "", path) sub("[/;_]$", "", path) v = split(path, P, "[/;_]") # curr = "root -> " q P[1] q # arrow_(curr) last = P[1] for(n = 2; n <= v; n++) { curr = q last q "->" q last "_" P[n] q arrow_(curr) last = last "_" P[n] } } function cleanup(s) { gsub("\260", "\\°", s) gsub("\\\\37777777660", "\\°", s) gsub("\\\\057", "/", s) return s } function node(path, desc, shape, orig) { orig=path desc=cleanup(desc) sub("^[/_;]", "", orig) sub("[/_;]$", "", orig) gsub("[/_;]", " ", orig) sub("^[/;]", "", path) sub("[/;]$", "", path) gsub("[/;]", "_", path) gsub("[\"]", "", desc) print q path q " [label=" q "{" orig "} \\n" desc q " " shape "]" arrow(path) } (($1 ~ "^[a-z]$") || ($1 ~ "^[a-z];[a-z];") || ($1 ~ "^[a-z];[a-z]$")) { node($1, $4, "") } END { print "}" } ' } gen_boxed_html() { $AWK -F '[\t]' ' /^[a-z][;]/ { key=substr($0, 1, 1) TBL[key] = TBL[key] "\n" $1 "" $4 } END { print "" print "

pcb-rnd 2.x.x keys - cheat sheet

" for(n = 0; n < 26; n++) { key = sprintf("%c", 97+n) print "
" print TBL[key] print "
" print "" } } ' } case "$cmd" in html) gen_list | gen_html ;; boxed) gen_list | gen_boxed_html ;; dot) gen_list | gen_dot ;; lst) gen_list ;; esac