From a99fbbfb27d99f6ce609ff49317ea61aa78db7ba Mon Sep 17 00:00:00 2001 From: Werner Almesberger Date: Fri, 27 May 2011 06:29:42 -0300 Subject: [PATCH] prod/doc/: added HTML macro processor (hmac) and page-specific style --- prod/doc/hmac.pl | 253 +++++++++++++++++++++++++++++++++++++++++++++ prod/doc/style.inc | 76 ++++++++++++++ 2 files changed, 329 insertions(+) create mode 100755 prod/doc/hmac.pl create mode 100644 prod/doc/style.inc diff --git a/prod/doc/hmac.pl b/prod/doc/hmac.pl new file mode 100755 index 0000000..4a19689 --- /dev/null +++ b/prod/doc/hmac.pl @@ -0,0 +1,253 @@ +#!/usr/bin/perl +# +# hmac.pl - Simple macro pre-processor for HTML +# +# Written 2001 by Werner Almesberger +# Copyright 2001 EPFL DSC-ICA, Network Robots +# + +#------------------------------------------------------------------------------ +# +# hmac processes macro definitions of the following type: +# +# ... +# +# The macro is invoked with or with +# ... +# +# HTML tags corresponding to the parameters (e.g. ) are expanded in +# the macro body. Parameters for which no default value was given must be +# specified. +# +# In the block-style invocation, the content of the block is assigned to +# the parameter BODY. Block-style invocations cannot be nested. +# +# Macros and macro definitions are processed in the order in which they appear +# in the input file. Macro definitions inside macros are processed when the +# outer macro is expanded. +# +# Files can be included with the tag. File inclusions +# are made as we go. +# +# hmac is not case-sensitive. +# +#------------------------------------------------------------------------------ + +# +# Marker +# +$BM = "\001"; +$EM = "\002"; + +# +# Collect -Dmacro=value options +# +while ($ARGV[0] =~ /^-D([^=]+)=/) { + $mac{$1} = $'; + shift(@ARGV); +} + +# +# Complain about unrecognized options +# +if ($ARGV[0] =~ /^-/) { + print STDERR "usage: $0 [-Dmacro=value ...] file ...\n"; + exit(1); +} + +# +# Read input and put warning +# +$in = join("",<>); +$in =~ s/\n/\n\n\n\n/; + +# +# Scan text for macros or includes +# +while (1) { + $first_macdef = &find_macdef($in); + $first_macro = &find_macro($in); + $first_include = &find_include($in); + last if $first_macdef == -1 && $first_macro == -1 && $first_include == -1; + if ($first_include != -1 && + ($first_include < $first_macro || $first_macro == -1) && + ($first_include < $first_macdef || $first_macdef == -1)) { + $in = &include_file($in); + } + else { + if (($first_macdef < $first_macro && $first_macdef != -1) || + $first_macro == -1) { + $in = &define_macro($in); + } + else { + $in = &expand_macro($in); + } + } +} +print $in; + + +# +# Find includes, and macros and their definitions +# + +sub find_include +{ + local ($in) = @_; + return -1 unless $in =~ /\s*/i; + $name = defined $2 ? $2 : $1; + undef $f; + open(FILE,$name) || die "open $name: $!"; + $f = $`.join("",).$'; + close FILE; + return $f; +} + + +# +# Extract first macro definition +# + +sub define_macro +{ + local ($in) = @_; + local ($a,$b,$c,$d); + + $in =~ s/|$EM|gi; + if ($in =~ /$BM(("[^"]*"|[^>])*)>/is) { + ($a,$b,$c) = ($`,$1,$'); + $d = ""; + $need = 1; + while ($need) { + $bm = index($c,$BM); + $em = index($c,$EM); + die " without " if $em == -1; + if ($bm < $em && $bm != -1) { + $d .= substr($c,0,$bm+1,""); + $need++; + } + else { + $d .= substr($c,0,$em+1,""); + $need--; + } + } + $c =~ s/^\s*//s; + $in = $a.$c; + chop($d); # remove last $EM + undef $name; + undef %arg; + $b =~ s/^\s*//; + while ($b =~ /^([a-z_][a-z0-9_]*)(=("([^"]*)"|\S+))?\s*/is) { + $b = $'; + ($prm = $1) =~ tr/a-z/A-Z/; + if ($prm eq "NAME") { + die "duplicate NAME" if defined $name; + die "NAME without value" unless defined $2; + ($name = defined $4 ? $4 : $3) =~ tr/a-z/A-Z/; + next; + } + die "reserved parameter name BODY" if $prm eq "BODY"; + die "duplicate parameter \"$prm\"" if exists $arg{$prm}; + $arg{$prm} = defined $2 ? defined $4 ? $4 : $3 : undef; + } + die "syntax error" unless $b eq ""; + die "NAME parameter is missing" unless defined $name; + $d =~ s/$BM/|gi; + $mac{$name} = $d; + $args{$name} = { %arg }; + } + else { + die " without " if $in =~ m|$EM|; + } + $in =~ s/$BM/|gi; + return $in; +} + + +# +# Expand first macro +# + +sub expand_macro +{ + local ($in) = @_; + local ($found,$a,$b,$c); + + undef $a; + for $mac (keys %mac) { + if ($in =~ /<$mac\b(("[^"]*"|[^>])*)>/is) { + ($a,$b,$c) = ($`,$1,$') if length $` < length $a || !defined $a; + } + next unless defined $a; + undef %arg; + %arg = %{ $args{$mac} }; + if ($c =~ m||i) { + $arg{"BODY"} = $`; + $c = $'; + } + else { + $arg{"BODY"} = undef; + } + $b =~ s/^\s*//; + while ($b =~ /^([a-z_][a-z0-9_]*)(=("([^"]*)"|\S+))\s*/is) { + $b = $'; + ($prm = $1) =~ tr/a-z/A-Z/; + die "unrecognized parameter \"$prm\"" unless exists $arg{$prm}; + $arg{$prm} = defined $2 ? defined $4 ? $4 : $3 : undef; + } + $b = $mac{$mac}; + while (1) { + $done = 1; + for (keys %arg) { + while ($b =~ /<$_>/i) { + $done = 0; + die "required parameter $_ is missing in macro $mac" + unless defined $arg{$_}; + $b = $`.$arg{$_}.$'; + } + } + last if $done; + } + return $a.$b.$c; + } + return $in; +} diff --git a/prod/doc/style.inc b/prod/doc/style.inc new file mode 100644 index 0000000..986c749 --- /dev/null +++ b/prod/doc/style.inc @@ -0,0 +1,76 @@ + + + + + + + + +
+
+
+ + + + +
+
+
+ + + + + <__PI bgcolor="#d080ff"></B></A></__PI> + <TD align="left"> + <TABLE border=0 cellspacing=0 cellpadding=0> + <TR> + <BODY> + <__PI_SEP> + <TD align="left" width="99%" bgcolor="#d080ff"> + </TABLE> +</MACRO> + +<MACRO name="PAGE_ITEM" href> + <__PI_SEP> + <__PI bgcolor="#c0d0ff"><A href="<HREF>"><BODY></A></__PI> +</MACRO> + +<MACRO name="PAGE_CURR" href> + <__PI_SEP> + <__PI bgcolor="#ffff00"><BODY></__PI> +</MACRO> + +<MACRO name="SECTION_BAR" title> + <TR><TD align="left" bgcolor="#ffffff"> + <TD align="left"> + <TABLE border=0 cellspacing=0 cellpadding=0> + <TR> + <BODY> + <__PI_SEP> + <TD align="left" width="99%" bgcolor="#d080ff"> + </TABLE> + </TABLE> +</MACRO> + +<MACRO name="SECTION_ITEM" href> + <__PI_SEP> + <TD align="center"> + <TABLE border=0 cellspacing=3 cellpadding=2 bgcolor="#ffff00"> + <TR><TD nowrap="nowrap"><A href="<HREF>"<FONT size="+2"><B><BODY></B></A> + </TABLE> +</MACRO> + +<MACRO name="SECTION" ref title> + <P> + <TABLE width="99%" border=0 cellspacing=0 cellpadding=2 bgcolor="#f0f0a0"> + <TR><TD> <A name="<REF>"><FONT + size="+2"><B><TITLE></B></FONT></A></TD> + </TABLE></TD> + <P> +</MACRO> + +<MACRO name="SUBSECTION" title> +<P> +<B><FONT size="+1"><TITLE></B></FONT> +<P> +</MACRO>