PageRenderTime 72ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/frameworks/trunk/zziplib/libzziplib/docs/mksite.pl

#
Perl | 1980 lines | 1777 code | 85 blank | 118 comment | 165 complexity | 58feb584b2486dc1ae082c490b6a8963 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, BSD-3-Clause, GPL-3.0, LGPL-3.0, MPL-2.0-no-copyleft-exception, Zlib, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. #! /usr/bin/perl
  2. # this is the perl variant of the mksite script. It based directly on a
  3. # copy of mksite.sh which is derived from snippets that I was using to
  4. # finish doc pages for website publishing. Using only sh/sed along with
  5. # files has a great disadvantage: it is a very slow process atleast. The
  6. # perl language in contrast has highly optimized string, replace, search
  7. # functions as well as data structures to store intermediate values. As
  8. # an advantage large parts of the syntax are similar to the sh/sed variant.
  9. #
  10. # http://zziplib.sf.net/mksite/
  11. # THE MKSITE.SH (ZLIB/LIBPNG) LICENSE
  12. # Copyright (c) 2004 Guido U. Draheim <guidod@gmx.de>
  13. # This software is provided 'as-is', without any express or implied warranty
  14. # In no event will the authors be held liable for any damages arising
  15. # from the use of this software.
  16. # Permission is granted to anyone to use this software for any purpose,
  17. # including commercial applications, and to alter it and redistribute it
  18. # freely, subject to the following restrictions:
  19. # 1. The origin of this software must not be misrepresented; you must not
  20. # claim that you wrote the original software. If you use this software
  21. # in a product, an acknowledgment in the product documentation would be
  22. # appreciated but is not required.
  23. # 2. Altered source versions must be plainly marked as such, and must not
  24. # be misrepresented as being the original software.
  25. # 3. This notice may not be removed or altered from any source distribution.
  26. # $Id: mksite.pl,v 1.2 2006-09-22 00:33:22 guidod Exp $
  27. use strict; use warnings; no warnings "uninitialized";
  28. use File::Basename qw(basename);
  29. use POSIX qw(strftime);
  30. # initialize some defaults
  31. my $SITEFILE="";
  32. $SITEFILE="site.htm" if not $SITEFILE and -f "site.htm";
  33. $SITEFILE="site.html" if not $SITEFILE and -f "site.html";
  34. $SITEFILE="site.htm" if not $SITEFILE;
  35. # my $MK="-mksite"; # note the "-" at the start
  36. my $SED="sed";
  37. my $DATA="~~"; # extension for meta data files
  38. my $HEAD="~head~"; # extension for head sed script
  39. my $BODY="~body~"; # extension for body sed script
  40. my $FOOT="~foot~"; # append to body text (non sed)
  41. my $SED_LONGSCRIPT="$SED -f";
  42. my $az="a-z"; # for perl
  43. my $AZ="A-Z"; # we may assume there are
  44. my $NN="0-9"; # char-ranges available
  45. my $AA="_$NN$AZ$az"; # that makes the resulting
  46. my $AX="$AA.+-"; # script more readable
  47. my $n = "\n";
  48. my $Q = "q class";
  49. my $QX = "/q";
  50. # LANG="C" ; LANGUAGE="C" ; LC_COLLATE="C" # these are needed for proper
  51. # export LANG LANGUAGE LC_COLLATE # lowercasing as some collate
  52. # treat A-Z to include a-z
  53. my @HTMLTAGS = qw/a p h1 h2 h3 h4 h5 h6 dl dd dt ul ol li pre code
  54. table tr td th b u i s q em strong strike cite big small sup sub tt
  55. thead tbody center hr br nobr wbr span div img adress blockquote/;
  56. my @HTMLTAGS2 = qw/html head body title meta http-equiv style link/;
  57. # ==========================================================================
  58. my $hint="";
  59. sub echo
  60. {
  61. print join(" ",@_),$n;
  62. }
  63. sub error
  64. {
  65. print STDERR "ERROR: ", join(" ",@_),$n;
  66. }
  67. sub warns
  68. {
  69. print STDERR "WARN: ", join(" ",@_), $n;
  70. }
  71. sub hint
  72. {
  73. print STDERR "NOTE: ", join(" ", @_), $n if $hint;
  74. }
  75. sub init
  76. {
  77. $hint="1" if -d "DEBUG";
  78. }
  79. &init ("NOW!!!");
  80. sub ls_s {
  81. my $x=`ls -s @_`;
  82. chomp($x);
  83. return $x;
  84. }
  85. # ==========================================================================
  86. # reading options from the command line GETOPT
  87. my %o = (); # to store option variables
  88. $o{variables}="files";
  89. $o{fileseparator}="?";
  90. $o{files}="";
  91. $o{main_file}="";
  92. $o{formatter}="$0";
  93. my $opt="";
  94. for my $arg (@ARGV) { # this variant should allow to embed spaces in $arg
  95. if ($opt) {
  96. $o{$opt}=$arg;
  97. $opt="";
  98. } else {
  99. $_=$arg;
  100. if (/^-.*=.*$/) {
  101. $opt=$arg; $opt =~ s/-*([$AA][$AA-]*).*/$1/; $opt =~ y/-/_/;
  102. if (not $opt) {
  103. error "invalid option $arg";
  104. } else {
  105. $arg =~ s/^[^=]*=//;
  106. $o{$opt} = $arg;
  107. $o{variables} .= " ".$opt;
  108. }
  109. $opt="";;
  110. } elsif (/^-.*.-.*$/) {
  111. $opt=$arg; $opt =~ s/-*([$AA][$AA-]*).*/$1/; $opt =~ y/-/_/;
  112. if (not $opt) {
  113. error "invalid option $arg";
  114. $opt="";
  115. } else {
  116. # keep the option for next round
  117. } ;;
  118. } elsif (/^-.*/) {
  119. $opt=$arg; $opt =~ s/^-*([$AA][$AA-]*).*/$1/; $opt =~ y/-/_/;
  120. if (not $opt) {
  121. error "invalid option $arg";
  122. } else {
  123. $arg =~ s/^[^=]*=//;
  124. $o{$opt} = ' ';
  125. }
  126. $opt="" ;;
  127. } else {
  128. hint "<$arg>";
  129. if (not $o{main_file}) { $o{main_file} = $arg; } else {
  130. $o{files} .= $o{fileseparator} if $o{files};
  131. $o{files} .= $arg; };
  132. $opt="" ;;
  133. };
  134. }
  135. } ; if ($opt) {
  136. $o{$opt}=" ";
  137. $opt="";
  138. }
  139. ### env | grep ^opt
  140. $SITEFILE=$o{main_file} if $o{main_file} and -f $o{main_file};
  141. $SITEFILE=$o{site_file} if $o{site_file} and -f $o{site_file};
  142. $hint="1" if $o{debug};
  143. if ($o{help}) {
  144. $_=$SITEFILE;
  145. echo "$0 [sitefile]";
  146. echo " default sitefile = $_ ($o{main_file}) ($o{files})";
  147. echo "options:";
  148. echo " --filelist : show list of target files as ectracted from $_";
  149. echo " --src-dir xx : if source files are not where mksite is executed";
  150. echo " --tmp-dir xx : use temp instead of local directory";
  151. echo " --tmp : use automatic temp directory in \$TEMP/mksite.*";
  152. exit;
  153. echo " internal:";
  154. echo "--fileseparator=x : for building the internal filelist (def. '?')";
  155. echo "--files xx : for list of additional files to be processed";
  156. echo "--main-file xx : for the main sitefile to take file list from";
  157. }
  158. if (not $SITEFILE) {
  159. error "no SITEFILE found (default would be 'site.htm')$n";
  160. exit 1;
  161. } else {
  162. hint "sitefile: ", ls_s($SITEFILE);
  163. }
  164. # we use internal hashes to store mappings - kind of relational tables
  165. my @MK_TAGS= (); # "./$MK.tags.tmp"
  166. my @MK_VARS= (); # "./$MK.vars.tmp"
  167. my @MK_SPAN= (); # "./$MK.span.tmp"
  168. my @MK_META= (); # "./$MK.meta.tmp"
  169. my @MK_METT= (); # "./$MK.mett.tmp"
  170. my @MK_TEST= (); # "./$MK.test.tmp"
  171. my @MK_FAST= (); # "./$MK.fast.tmp"
  172. my @MK_GETS= (); # "./$MK.gets.tmp"
  173. my @MK_PUTS= (); # "./$MK.puts.tmp"
  174. my @MK_OLDS= (); # "./$MK.olds.tmp"
  175. my @MK_SITE= (); # "./$MK.site.tmp"
  176. my @MK_SECT1= (); # "./$MK.sect1.tmp"
  177. my @MK_SECT2= (); # "./$MK.sect2.tmp"
  178. my @MK_SECT3= (); # "./$MK.sect3.tmp"
  179. my @MK_DATA= (); # "./$MK~~"
  180. my %DATA= (); # used for $F.$PARTs
  181. # ========================================================================
  182. # ========================================================================
  183. # ========================================================================
  184. # MAGIC VARS
  185. # IN $SITEFILE
  186. my $printerfriendly="";
  187. my $sectionlayout="list";
  188. my $sitemaplayout="list";
  189. my $attribvars=" "; # <x ref="${varname:=default}">
  190. my $updatevars=" "; # <!--$varname:=-->default
  191. my $expandvars=" "; # <!--$varname-->
  192. my $commentvars=" "; # $updatevars && $expandsvars
  193. my $sectiontab=" "; # highlight ^<td class=...>...href="$section"
  194. my $currenttab=" "; # highlight ^<br>..<a href="$topic">
  195. my $headsection="no";
  196. my $tailsection="no";
  197. my $sectioninfo="no"; # using <h2> title <h2> = info text
  198. my $emailfooter="no";
  199. for (source($SITEFILE)) {
  200. if (/<!--multi-->/) {
  201. warns("do not use <!--multi-->,"
  202. ." change to <!--mksite:multi--> $SITEFILE"
  203. ."warning: or"
  204. ." <!--mksite:multisectionlayout-->"
  205. ." <!--mksite:multisitemaplayout-->");
  206. $sectionlayout="multi";
  207. $sitemaplayout="multi";
  208. }
  209. if (/<!--mksite:multi-->/) {
  210. $sectionlayout="multi";
  211. $sitemaplayout="multi";
  212. }
  213. if (/<!--mksite:multilayout-->/) {
  214. $sectionlayout="multi";
  215. $sitemaplayout="multi";
  216. }
  217. }
  218. sub mksite_magic_option
  219. {
  220. # $1 is word/option to check for
  221. my ($U,$INP,$Z) = @_;
  222. $INP=$SITEFILE if not $INP;
  223. for (source($INP)) {
  224. s/(<!--mksite:)($U)-->/$1$2: -->/g;
  225. s/(<!--mksite:)(\w\w*)($U)-->/$1$3:$2-->/g;
  226. /<!--mksite:$U:/ or next;
  227. s/.*<!--mksite:$U:([^<>]*)-->.*/$1/;
  228. s/.*<!--mksite:$U:([^-]*)-->.*/$1/;
  229. /<!--mksite:$U:/ and next;
  230. chomp;
  231. return $_;
  232. }
  233. return "";
  234. }
  235. {
  236. my $x;
  237. $x=mksite_magic_option("sectionlayout"); if
  238. ($x =~ /^(list|multi)$/) { $sectionlayout="$x" ; }
  239. $x=mksite_magic_option("sitemaplayout"); if
  240. ($x =~ /^(list|multi)$/) { $sitemaplayout="$x" ; }
  241. $x=mksite_magic_option("attribvars"); if
  242. ($x =~ /^( |no|warn)$/) { $attribvars="$x" ; }
  243. $x=mksite_magic_option("updatevars"); if
  244. ($x =~ /^( |no|warn)$/) { $updatevars="$x" ; }
  245. $x=mksite_magic_option("expandvars"); if
  246. ($x =~ /^( |no|warn)$/) { $expandvars="$x" ; }
  247. $x=mksite_magic_option("commentvars"); if
  248. ($x =~ /^( |no|warn)$/) { $commentvars="$x" ; }
  249. $x=mksite_magic_option("printerfriendly"); if
  250. ($x =~ /^( |[.].*|[-]-.*)$/) { $printerfriendly="$x" ; }
  251. $x=mksite_magic_option("sectiontab"); if
  252. ($x =~ /^( |no|warn)$/) { $sectiontab="$x" ; }
  253. $x=mksite_magic_option("currenttab"); if
  254. ($x =~ /^( |no|warn)$/) { $currenttab="$x" ; }
  255. $x=mksite_magic_option("sectioninfo"); if
  256. ($x =~ /^( |no|[=:-])$/) { $sectioninfo="$x" ; }
  257. $x=mksite_magic_option("commentvars"); if
  258. ($x =~ /^( |no|warn)$/) { $commentvars="$x" ; }
  259. $x=mksite_magic_option("emailfooter"); if
  260. ($x) { $emailfooter="$x"; }
  261. }
  262. $printerfriendly=$o{print} if $o{print};
  263. $updatevars="no" if $commentvars eq "no"; # duplicated into
  264. $expandvars="no" if $commentvars eq "no"; # info2vars_sed
  265. hint "'$sectionlayout\'sectionlayout '$sitemaplayout\'sitemaplayout";
  266. hint "'$attribvars\'attribvars '$updatevars\'updatevars";
  267. hint "'$expandvars\'expandvars '$commentvars\'commentvars";
  268. hint "'$currenttab\'currenttab '$sectiontab\'sectiontab";
  269. hint "'$headsection\'headsection '$tailsection\'tailsection";
  270. # ==========================================================================
  271. # init a few global variables
  272. # 0. INIT
  273. # $MK.tags.tmp - originally, we would use a lambda execution on each
  274. # uppercased html tag to replace <P> with <p class="P">. Here we just
  275. # walk over all the known html tags and make an sed script that does
  276. # the very same conversion. There would be a chance to convert a single
  277. # tag via "h;y;x" or something we do want to convert all the tags on
  278. # a single line of course.
  279. @MK_TAGS=();
  280. { my ($M,$P); for $M (@HTMLTAGS) {
  281. $P=uc($M);
  282. push @MK_TAGS, "s|<$P>|<$M class=\\\"$P\\\">|g;";
  283. push @MK_TAGS, "s|<$P |<$M class=\\\"$P\\\" |g;";
  284. push @MK_TAGS, "s|</$P>|</$M>|g;";
  285. }}
  286. push @MK_TAGS, "s|<>|\\&nbsp\\;|g;";
  287. push @MK_TAGS, "s|<->|<WBR />\\;|g;";
  288. push @MK_TAGS, "s|<c>|<code>|g;";
  289. push @MK_TAGS, "s|</c>|</code>|g;";
  290. push @MK_TAGS, "s|<section>||g;";
  291. push @MK_TAGS, "s|</section>||g;";
  292. push @MK_TAGS, "s|<(a [^<>]*) />|<\$1></a>|g";
  293. my $_ulink_="<a href=\"\$1\" remap=\"url\">\$1</a>";
  294. push @MK_TAGS, "s|<a>\\s*(\\w+://[^<>]*)</a>|$_ulink_|g;";
  295. # also make sure that some non-html entries are cleaned away that
  296. # we are generally using to inject meta information. We want to see
  297. # that meta ino in the *.htm browser view during editing but they
  298. # shall not get present in the final html page for publishing.
  299. my @DC_VARS =
  300. ("contributor", "date", "source", "language", "coverage", "identifier",
  301. "rights", "relation", "creator", "subject", "description",
  302. "publisher", "DCMIType");
  303. my @_EQUIVS =
  304. ("refresh", "expires", "content-type", "cache-control",
  305. "redirect", "charset", # mapped to refresh / content-type
  306. "content-language", "content-script-type", "content-style-type");
  307. { my $P; for $P (@DC_VARS) { # dublin core embedded
  308. push @MK_TAGS, "s|<$P>[^<>]*</$P>||g;";
  309. }}
  310. { my $P; for $P (@_EQUIVS) {
  311. push @MK_TAGS, "s|<$P>[^<>]*</$P>||g;";
  312. }}
  313. push @MK_TAGS, "s|<a sect=\\\"[$AZ$NN]\\\"|<a|g;" if not $o{keepsect};
  314. push @MK_TAGS, "s|<!--[$AX]*[?]-->||g;";
  315. push @MK_TAGS, "s|<!--\\\$[$AX]*[?]:-->||g;";
  316. push @MK_TAGS, "s|<!--\\\$[$AX]*:[?=]-->||g;";
  317. push @MK_TAGS, "s|(<[^<>]*)\\\${[$AX]*:[?=]([^<{}>]*)}([^<>]*>)|\$1\$2\$3|g;";
  318. my $TRIMM=" -e 's:^ *::' -e 's: *\$::'"; # trimm away leading/trailing spaces
  319. sub trimm
  320. {
  321. my ($T,$Z) = @_;
  322. $T =~ s:\A\s*::s; $T =~ s:\s*\Z::s;
  323. return $T;
  324. }
  325. sub trimmm
  326. {
  327. my ($T,$Z) = @_;
  328. $T =~ s:\A\s*::s; $T =~ s:\s*\Z::s; $T =~ s:\s+: :g;
  329. return $T;
  330. }
  331. sub timezone
  332. {
  333. # +%z is an extension while +%Z is supposed to be posix
  334. my $tz;
  335. eval { $tz = strftime("%z", localtime()) };
  336. return $tz if $tz =~ /[+]/;
  337. return $tz if $tz =~ /[-]/;
  338. return strftime("%Z", localtime());
  339. }
  340. sub timetoday
  341. {
  342. return strftime("%Y-%m-%d", localtime());
  343. }
  344. sub timetodays
  345. {
  346. return strftime("%Y-%m%d", localtime());
  347. }
  348. sub esc
  349. {
  350. my ($TXT,$XXX) = @_;
  351. $TXT =~ s|&|\\\\&|g;
  352. return $TXT;
  353. }
  354. my %SOURCE;
  355. sub source # $file : @lines
  356. {
  357. my ($FILE,$Z) = @_;
  358. if (exists $SOURCE{$FILE}) { return @{$SOURCE{$FILE}}; }
  359. my @TEXT = ();
  360. open FILE, "<$FILE" or die "could not open $FILE: $!";
  361. for my $line (<FILE>) {
  362. push @TEXT, $line;
  363. } close FILE;
  364. @{$SOURCE{$FILE}} = @TEXT;
  365. return @{$SOURCE{$FILE}};
  366. }
  367. sub savesource # $file \@lines
  368. {
  369. my ($FILE,$LINES,$Z) = @_;
  370. @{$SOURCE{$FILE}} = @{$LINES};
  371. }
  372. my $F; # current file during loop <<<<<<<<<
  373. my $i = 100;
  374. sub savelist {
  375. if (-d "DEBUG") {
  376. my ($script,$ext,$Z) = @_;
  377. if (not $ext) { $ext = "_".$i; $i++; }
  378. my $X = "$F.$ext.tmp.PL"; $X =~ s|/|:|g;
  379. open X, ">DEBUG/$X" or die "could not open $X: $!";
  380. print X "#! /usr/bin/env perl",$n;
  381. print X "# ",$#_," $ext files ",localtime(),$n;
  382. my $TEXT = join("$n", @{$script});
  383. $TEXT =~ s|source\([^()]*\)|<>|;
  384. print X $TEXT,$n; close X;
  385. }
  386. }
  387. sub eval_MK_LIST # $str @list
  388. {
  389. my $FILETYPE = $_[0]; shift @_;
  390. my $result = $_[0]; shift @_;
  391. my $extra = "";
  392. my $script = "\$_ = \$result; my \$Z;";
  393. $script .= join(";$n ", @_);
  394. $script .= "$n;\$result = \$_;$n";
  395. savelist([$script],$FILETYPE);
  396. eval $script;
  397. return $result.$extra;
  398. }
  399. sub eval_MK_FILE {
  400. my $FILETYPE = $_[0]; shift @_;
  401. my $FILENAME = $_[0]; shift @_;
  402. my $result = "";
  403. my $script = "my \$FILE; my \$extra = ''; my \$Z; $n";
  404. $script.= "for (source('$FILENAME')) { $n";
  405. $script.= join(";$n ", @_);
  406. $script.= "$n; \$result .= \$_; ";
  407. $script.= "$n if(\$extra){\$result.=\$extra;\$extra='';\$result.=\"\\n\"}";
  408. $script.= "$n} if(\$extra){\$result.=\$extra;}$n";
  409. savelist([$script],$FILETYPE);
  410. eval $script;
  411. return $result;
  412. }
  413. my $sed_add = "\$extra .= "; # "/r ";
  414. sub foo { print " '$F'$n"; }
  415. # ======================================================================
  416. # FUNCS
  417. my $SOURCEFILE; # current file <<<<<<<<
  418. my @FILELIST; # <<<<<<<
  419. sub sed_slash_key # helper to escape chars special in /anchor/ regex
  420. { # currently escaping "/" "[" "]" "."
  421. my $R = $_[0]; $R =~ s|[\"./[-]|\\$&|g; $R =~ s|\]|\\\\$&|g;
  422. return $R;
  423. }
  424. sub sed_piped_key # helper to escape chars special in s|anchor|| regex
  425. { # currently escaping "|" "[" "]" "."
  426. my $R = $_[0]; $R =~ s/[\".|[-]/\\$&/g; $R =~ s/\]/\\\\$&/g;
  427. return $R;
  428. }
  429. sub back_path # helper to get the series of "../" for a given path
  430. {
  431. my ($R,$Z) = @_; if ($R !~ /\//) { return ""; }
  432. $R =~ s|/[^/]*$|/|; $R =~ s|[^/]*/|../|g;
  433. return $R;
  434. }
  435. sub dir_name
  436. {
  437. my $R = $_[0]; $R =~ s:/[^/][^/]*\$::;
  438. return $R;
  439. }
  440. sub info2vars_sed # generate <!--$vars--> substition sed addon script
  441. {
  442. my ($INP,$Z) = @_;
  443. $INP = \@{$DATA{$F}} if not $INP;
  444. my @OUT = ();
  445. my $V8=" *([^ ][^ ]*) +(.*)<$QX>";
  446. my $V9=" *DC[.]([^ ][^ ]*) +(.*)<$QX>";
  447. my $N8=" *([^ ][^ ]*) ([$NN].*)<$QX>";
  448. my $N9=" *DC[.]([^ ][^ ]*) ([$NN].*)<$QX>";
  449. my $V0="([<]*)\\\$";
  450. my $V1="([^<>]*)\\\$";
  451. my $V2="([^{<>}]*)";
  452. my $V3="([^<>]*)";
  453. my $SS="<"."<>".">"; # spacer so value="2004" dont make for s|\(...\)|\12004|
  454. $Z="\$Z=";
  455. $updatevars = "no" if $commentvars eq "no"; # duplicated from
  456. $expandvars = "no" if $commentvars eq "no"; # option handling
  457. my @_INP = (); for (@{$INP}) {
  458. my $x=$_; $x =~ s/(>[^<>]*)'([^<>]*<)/$1\\'$2/; push @_INP, $x; # OOOOPS
  459. }
  460. if ($expandvars ne "no") {
  461. for (@_INP) {
  462. if (/^=....=formatter /) { next; }
  463. elsif (/^<$Q='name'>$V9/){push @OUT, "\$Z='$2';s|<!--$V0$1\\?-->|- \$Z|;"}
  464. elsif (/^<$Q='Name'>$V9/){push @OUT, "\$Z='$2';s|<!--$V0$1\\?-->|(\$Z)|;"}
  465. elsif (/^<$Q='name'>$V8/){push @OUT, "\$Z='$2';s|<!--$V0$1\\?-->|- \$Z|;"}
  466. elsif (/^<$Q='Name'>$V8/){push @OUT, "\$Z='$2';s|<!--$V0$1\\?-->|(\$Z)|;"}
  467. }
  468. }
  469. if ($expandvars ne "no") {
  470. for (@_INP) {
  471. if (/^=....=formatter /) { next; }
  472. elsif (/^<$Q='text'>$V9/){push @OUT, "\$Z='$2';s|<!--$V1$1-->|\$1$SS\$Z|;"}
  473. elsif (/^<$Q='Text'>$V9/){push @OUT, "\$Z='$2';s|<!--$V1$1-->|\$1$SS\$Z|;"}
  474. elsif (/^<$Q='name'>$V9/){push @OUT, "\$Z='$2';s|<!--$V1$1\\?-->|\$1$SS\$Z|;"}
  475. elsif (/^<$Q='Name'>$V9/){push @OUT, "\$Z='$2';s|<!--$V1$1\\?-->|\$1$SS\$Z|;"}
  476. elsif (/^<$Q='text'>$V8/){push @OUT, "\$Z='$2';s|<!--$V1$1-->|\$1$SS\$Z|;"}
  477. elsif (/^<$Q='Text'>$V8/){push @OUT, "\$Z='$2';s|<!--$V1$1-->|\$1$SS\$Z|;"}
  478. elsif (/^<$Q='name'>$V8/){push @OUT, "\$Z='$2';s|<!--$V1$1\\?-->|\$1$SS\$Z|;"}
  479. elsif (/^<$Q='Name'>$V8/){push @OUT, "\$Z='$2';s|<!--$V1$1\\?-->|\$1$SS\$Z|;"}
  480. }
  481. }
  482. if ($updatevars ne "no") {
  483. for (@_INP) { my $H = "[^<>]*";
  484. if (/^=....=formatter /) { next; }
  485. elsif (/^<$Q='name'>$V9/){push @OUT, "\$Z='$2';s|<!--$V0$1:\\?-->$H|- \$Z|;"}
  486. elsif (/^<$Q='Name'>$V9/){push @OUT, "\$Z='$2';s|<!--$V0$1:\\?-->$H|(\$Z)|;"}
  487. elsif (/^<$Q='name'>$V8/){push @OUT, "\$Z='$2';s|<!--$V0$1:\\?-->$H|- \$Z|;"}
  488. elsif (/^<$Q='Name'>$V8/){push @OUT, "\$Z='$2';s|<!--$V0$1:\\?-->$H|(\$Z)|;"}
  489. }
  490. }
  491. if ($updatevars ne "no") {
  492. for (@_INP) { my $H = "[^<>]*";
  493. if (/^=....=formatter /) { next; }
  494. elsif (/^<$Q='text'>$V9/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\=-->$H|\$1$SS\$Z|;"}
  495. elsif (/^<$Q='Text'>$V9/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\=-->$H|\$1$SS\$Z|;"}
  496. elsif (/^<$Q='name'>$V9/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\?-->$H|\$1$SS\$Z|;"}
  497. elsif (/^<$Q='Name'>$V9/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\?-->$H|\$1$SS\$Z|;"}
  498. elsif (/^<$Q='text'>$V8/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\=-->$H|\$1$SS\$Z|;"}
  499. elsif (/^<$Q='Text'>$V8/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\=-->$H|\$1$SS\$Z|;"}
  500. elsif (/^<$Q='name'>$V8/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\?-->$H|\$1$SS\$Z|;"}
  501. elsif (/^<$Q='Name'>$V8/){push @OUT,"\$Z='$2';s|<!--$V1$1:\\?-->$H|\$1$SS\$Z|;"}
  502. }
  503. }
  504. if ($attribvars ne "no") {
  505. for (@_INP) { my $H = "[^<>]*";
  506. if (/^=....=formatter /) { next; }
  507. elsif (/^<$Q='text'>$V9/){push @OUT,"\$Z='$2';s|<$V1\{$1:[=]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  508. elsif (/^<$Q='Text'>$V9/){push @OUT,"\$Z='$2';s|<$V1\{$1:[=]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  509. elsif (/^<$Q='name'>$V9/){push @OUT,"\$Z='$2';s|<$V1\{$1:[?]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  510. elsif (/^<$Q='Name'>$V9/){push @OUT,"\$Z='$2';s|<$V1\{$1:[?]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  511. elsif (/^<$Q='text'>$V8/){push @OUT,"\$Z='$2';s|<$V1\{$1:[=]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  512. elsif (/^<$Q='Text'>$V8/){push @OUT,"\$Z='$2';s|<$V1\{$1:[=]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  513. elsif (/^<$Q='name'>$V8/){push @OUT,"\$Z='$2';s|<$V1\{$1:[?]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  514. elsif (/^<$Q='Name'>$V8/){push @OUT,"\$Z='$2';s|<$V1\{$1:[?]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  515. }
  516. for (split / /, $o{variables}) {
  517. {push @OUT,"\$Z='$o{$_}';s|<$V1\{$_:[?]$V2}$V3>|<\$1$SS\$Z\$3>|;"}
  518. }
  519. }
  520. # if value="2004" then generated sed might be "\\12004" which is bad
  521. # instead we generate an edited value of "\\1$SS$value" and cut out
  522. # the spacer now after expanding the variable values:
  523. push @OUT, "s|$SS||g;";
  524. return @OUT;
  525. }
  526. sub info2meta_sed # generate <meta name..> text portion
  527. {
  528. my ($INP,$XXX) = @_;
  529. $INP = \@{$DATA{$F}} if not $INP;
  530. my @OUT = ();
  531. # http://www.metatab.de/meta_tags/DC_type.htm
  532. my $V6=" *HTTP[.]([^ ]+) (.*)<$QX>";
  533. my $V7=" *DC[.]([^ ]+) (.*)<$QX>";
  534. my $V8=" *([^ ]+) (.*)<$QX>" ;
  535. sub __TYPE_SCHEME { "name=\"DC.type\" content=\"$2\" scheme=\"$1\"" };
  536. sub __DCMI { "name=\"$1\" content=\"$2\" scheme=\"DCMIType\"" };
  537. sub __NAME { "name=\"$1\" content=\"$2\"" };
  538. sub __NAME_TZ { "name=\"$1\" content=\"$2 ".&timezone()."\"" };
  539. sub __HTTP { "http-equiv=\"$1\" content=\"$2\"" };
  540. for (@$INP) {
  541. if (/=....=today /) { next; }
  542. if (/<$Q='meta'>HTTP[.]/ && /<$Q='meta'>$V6/) {
  543. push @OUT, " <meta ${\(__HTTP)} />" if $2; next; }
  544. if (/<$Q='meta'>DC[.]DCMIType / && /<$Q='meta'>$V7/) {
  545. push @OUT, " <meta ${\(__TYPE_SCHEME)} />" if $2; next; }
  546. if (/<$Q='meta'>DC[.]type Collection$/ && /<$Q='meta'>$V8/) {
  547. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  548. if (/<$Q='meta'>DC[.]type Dataset$/ && /<$Q='meta'>$V8/) {
  549. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  550. if (/<$Q='meta'>DC[.]type Event$/ && /<$Q='meta'>$V8/) {
  551. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  552. if (/<$Q='meta'>DC[.]type Image$/ && /<$Q='meta'>$V8/) {
  553. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  554. if (/<$Q='meta'>DC[.]type Service$/ && /<$Q='meta'>$V8/) {
  555. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  556. if (/<$Q='meta'>DC[.]type Software$/ && /<$Q='meta'>$V8/) {
  557. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  558. if (/<$Q='meta'>DC[.]type Sound$/ && /<$Q='meta'>$V8/) {
  559. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  560. if (/<$Q='meta'>DC[.]type Text$/ && /<$Q='meta'>$V8/) {
  561. push @OUT, " <meta ${\(__DCMI)} />" if $2; next; }
  562. if (/<$Q='meta'>DC[.]date[.].*[+]/ && /<$Q='meta'>$V8/) {
  563. push @OUT, " <meta ${\(__NAME)} />" if $2; next; }
  564. if (/<$Q='meta'>DC[.]date[.].*[:]/ && /<$Q='meta'>$V8/) {
  565. push @OUT, " <meta ${\(__NAME_TZ)} />" if $2; next; }
  566. if (/<$Q='meta'>/ && /<$Q='meta'>$V8/) {
  567. push @OUT, " <meta ${\(__NAME)} />" if $2; next; }
  568. }
  569. return @OUT;
  570. }
  571. sub info_get_entry # get the first <!--vars--> value known so far
  572. {
  573. my ($TXT,$INP,$XXX) = @_;
  574. $TXT = "sect" if not $TXT;
  575. $INP = \@{$DATA{$F}} if not $INP;
  576. for (grep {/<$Q='text'>$TXT /} @$INP) {
  577. my $info = $_;
  578. $info =~ s|<$Q='text'>$TXT ||; $info =~ s|<$QX>||;
  579. chomp($info); chomp($info); return $info;
  580. }
  581. }
  582. sub info1grep # test for a <!--vars--> substition to be already present
  583. {
  584. my ($TXT,$INP,$XXX) = @_;
  585. $TXT = "sect" if not $TXT;
  586. $INP = \@{$DATA{$F}} if not $INP;
  587. return scalar(grep {/^<$Q='text'>$TXT /} @$INP); # returning the count
  588. }
  589. sub dx_init
  590. {
  591. @{$DATA{$F}} = ();
  592. &dx_meta ("formatter", basename($o{formatter}));
  593. for (split / /, $o{variables}) { # commandline --def=value
  594. if (/_/) { my $u=$_; $u =~ y/_/-/; # makes for <!--$def--> override
  595. &dx_meta ($u, $o{$_});
  596. } else { &dx_text ($_, $o{$_}); }
  597. }
  598. }
  599. sub dx_line
  600. {
  601. my ($U,$V,$W,$Z) = @_; chomp($U); chomp($V);
  602. push @{$DATA{$F}}, "<$Q=$U>".$V." ".trimmm($W)."<$QX>";
  603. }
  604. sub DX_line
  605. {
  606. my ($U,$V,$W,$Z) = @_; $W =~ s/<[^<>]*>//g;
  607. &dx_line ($U,$V,$W);
  608. }
  609. sub dx_text
  610. {
  611. my ($U,$V,$Z) = @_;
  612. &dx_line ("'text'",$U,$V);
  613. }
  614. sub DX_text # add a <!--vars--> substition includings format variants
  615. {
  616. my ($N, $T,$XXX) = @_;
  617. $N = trimm($N); $T = trimm($T);
  618. if ($N) {
  619. if ($T) {
  620. my $text=lc("$T"); $text =~ s/<[^<>]*>//g;
  621. &dx_line ("'text'",$N,$T);
  622. &dx_line ("'name'",$N,$text);
  623. my $varname=$N; $varname =~ s/.*[.]//; # cut out front part
  624. if ($N ne $varname and $varname) {
  625. $text=lc("$varname $T"); $text =~ s/<[^<>]*>//g;
  626. &dx_line ("'Text'",$varname,$T);
  627. &dx_line ("'Name'",$varname,$text);
  628. }
  629. }
  630. }
  631. }
  632. sub dx_meta
  633. {
  634. my ($U,$V,$Z) = @_;
  635. &DX_line ("'meta'",$U,$V);
  636. }
  637. sub DX_meta # add simple meta entry and its <!--vars--> subsitution
  638. {
  639. my ($U,$V,$Z) = @_;
  640. &DX_line ("'meta'",$U,$V);
  641. &DX_text ("$U", $V);
  642. }
  643. sub DC_meta # add new DC.meta entry plus two <!--vars--> substitutions
  644. {
  645. my ($U,$V,$Z) = @_;
  646. &DX_line ("'meta'","DC.$U",$V);
  647. &DX_text ("DC.$U", $V);
  648. &DX_text ("$U", $V);
  649. }
  650. sub HTTP_meta # add new HTTP.meta entry plus two <!--vars--> substitutions
  651. {
  652. my ($U,$V,$Z) = @_;
  653. &DX_line ("'meta'","HTTP.$U",$V);
  654. &DX_text ("HTTP.$U", $V);
  655. &DX_text ("$U", $V);
  656. }
  657. sub DC_VARS_Of # check DC vars as listed in $DC_VARS global/generate DC_meta
  658. { # the results will be added to .meta.tmp and .vars.tmp later
  659. my ($FILENAME,$Z)= @_;
  660. $FILENAME=$SOURCEFILE if not $FILENAME;
  661. for my $M (@DC_VARS, "title") {
  662. # scan for a <markup> of this name FIXME
  663. my ($part,$text);
  664. for (source($FILENAME)) {
  665. /<$M>/ or next; s|.*<$M>||; s|</$M>.*||;
  666. $part = trimm($_); last;
  667. }
  668. $text=$part; $text =~ s|^\w*:||; $text = trimm($text);
  669. next if not $text;
  670. # <mark:part> will be <meta name="mark.part">
  671. if ($text ne $part) {
  672. my $N=$part; $N =~ s/:.*//;
  673. &DC_meta ("$M.$N", $text);
  674. } elsif ($M eq "date") {
  675. &DC_meta ("$M.issued", $text); # "<date>" -> "<date>issued:"
  676. } else {
  677. &DC_meta ("$M", $text);
  678. }
  679. }
  680. }
  681. sub HTTP_VARS_Of # check HTTP-EQUIVs as listed in $_EQUIV global then
  682. { # generate meta tags that are http-equiv= instead of name=
  683. my ($FILENAME,$Z)= @_;
  684. $FILENAME=$SOURCEFILE if not $FILENAME;
  685. for my $M (@_EQUIVS) {
  686. # scan for a <markup> of this name FIXME
  687. my ($part,$text);
  688. for (source($FILENAME)) {
  689. /<$M>/ or next; s|.*<$M>||; s|</$M>.*||;
  690. $part = trimm($_); last;
  691. }
  692. $text=$part; $text =~ s|^\w*:||; $text = trimm($text);
  693. next if not $text;
  694. if ($M eq "redirect") {
  695. &HTTP_meta ("refresh", "5; url=$text"); &DX_text ("$M", $text);
  696. } elsif ($M eq "charset") {
  697. &HTTP_meta ("content-type", "text/html; charset=$text");
  698. } else {
  699. &HTTP_meta ("$M", $text);
  700. }
  701. }
  702. }
  703. sub DC_isFormatOf # make sure there is this DC.relation.isFormatOf tag
  704. { # choose argument for a fallback (usually $SOURCEFILE)
  705. my ($NAME,$Z) = @_;
  706. $NAME=$SOURCEFILE if not $NAME;
  707. if (not &info1grep ("DC.relation.isFormatOf")) {
  708. &DC_meta ("relation.isFormatOf", "$NAME");
  709. }
  710. }
  711. sub DC_publisher # make sure there is this DC.publisher meta tag
  712. { # choose argument for a fallback (often $USER)
  713. my ($NAME,$Z) = @_;
  714. $NAME=$ENV{"USER"} if not $NAME;
  715. if (not &info1grep ("DC.publisher")) {
  716. &DC_meta ("publisher", "$NAME");
  717. }
  718. }
  719. sub DC_modified # make sure there is a DC.date.modified meta tag
  720. { # maybe choose from filesystem dates if possible
  721. my ($ZZ,$Z) = @_; # target file
  722. if (not &info1grep ("DC.date.modified")) {
  723. my @stats = stat($ZZ);
  724. my $text = strftime("%Y-%m-%d", localtime($stats[9]));
  725. &DC_meta ("date.modified", $text);
  726. }
  727. }
  728. sub DC_date # make sure there is this DC.date meta tag
  729. { # choose from one of the available DC.date.* specials
  730. my ($ZZ,$Z) = @_; # source file
  731. if (&info1grep ("DC.date")) {
  732. &DX_text ("issue", "dated ".&info_get_entry("DC.date"));
  733. &DX_text ("updated", &info_get_entry("DC.date"));
  734. } else {
  735. my $text=""; my $kind;
  736. for $kind (qw/available issued modified created/) {
  737. $text=&info_get_entry("DC.date.$kind");
  738. # test ".$text" != "." && echo "$kind = date = $text ($ZZ)"
  739. last if $text;
  740. }
  741. if (not $text) {
  742. my $part; my $M="date";
  743. for (source($ZZ)) {
  744. /<$M>/ or next; s|.*<$M>||; s|</$M>.*||;
  745. $part=trimm($_); last;
  746. }
  747. $text=$part; $text =~ s|^[$AA]*:||;
  748. $text = &trimm ($text);
  749. }
  750. if (not $text) {
  751. my $part; my $M="!--date:*=*--"; # takeover updateable variable...
  752. for (source($ZZ)) {
  753. /<$M>/ or next; s|.*<$M>||; s|</.*||;
  754. $part=trimm($_); last;
  755. }
  756. $text=$part; $text =~ s|^[$AA]*:||; $text =~ s|\&.*||;
  757. $text = &trimm ($text);
  758. }
  759. $text =~ s/[$NN]*:.*//; # cut way seconds
  760. &DX_text ("updated", $text);
  761. my $text1=$text; $text1 =~ s|^.* *updated ||;
  762. if ($text ne $text1) {
  763. $kind="modified" ; $text=$text1; $text =~ s|,.*||;
  764. }
  765. $text1=$text; $text1 =~ s|^.* *modified ||;
  766. if ($text ne $text1) {
  767. $kind="modified" ; $text=$text1; $text =~ s|,.*||;
  768. }
  769. $text1=$text; $text1 =~ s|^.* *created ||;
  770. if ($text ne $text1) {
  771. $kind="created" ; $text=$text1; $text =~ s|,.*||;
  772. }
  773. &DC_meta ("date", "$text");
  774. &DX_text ("issue", "$kind $text");
  775. }
  776. }
  777. sub DC_title
  778. {
  779. # choose a title for the document, either an explicit title-tag
  780. # or one of the section headers in the document or fallback to filename
  781. my ($ZZ,$Z) = @_; # target file
  782. my ($term, $text);
  783. if (not &info1grep ("DC.title")) {
  784. for my $M (qw/TITLE title H1 h1 H2 h2 H3 H3 H4 H4 H5 h5 H6 h6/) {
  785. for (source($ZZ)) {
  786. /<$M>/ or next; s|.*<$M>||; s|</$M>.*||;
  787. $text = trimm($_); last;
  788. }
  789. last if $text;
  790. for (source($ZZ)) {
  791. /<$M [^<>]*>/ or next; s|.*<$M [^<>]*>||; s|</$M>.*||;
  792. $text = trimm($_); last;
  793. }
  794. last if $text;
  795. }
  796. if (not $text) {
  797. $text=basename($ZZ,".html");
  798. $text=basename($text,".htm"); $text =~ y/_/ /; $text =~ s/$/ info/;
  799. $text=~ s/\n/ /g;
  800. }
  801. $term=$text; $term =~ s/.*[\(]//; $term =~ s/[\)].*//;
  802. $text =~ s/[\(][^\(\)]*[\)]//;
  803. if (not $term or $term eq $text) {
  804. &DC_meta ("title", "$text");
  805. } else {
  806. &DC_meta ("title", "$term - $text");
  807. }
  808. }
  809. }
  810. sub site_get_section # return parent section page of given page
  811. {
  812. my $_F_ = &sed_slash_key(@_);
  813. for my $x (grep {/<$Q='sect'>$_F_ /} @MK_DATA) {
  814. my $info = $x; $info =~ s|<$Q='sect'>[^ ]* ||; $info =~ s|<$QX>||;
  815. return $info;
  816. }
  817. }
  818. sub DC_section # not really a DC relation (shall we use isPartOf ?)
  819. { # each document should know its section father
  820. my $sectn = &site_get_section($F);
  821. if ($sectn) {
  822. &DC_meta ("relation.section", $sectn);
  823. }
  824. }
  825. sub info_get_entry_section
  826. {
  827. return &info_get_entry("DC.relation.section");
  828. }
  829. sub site_get_selected # return section of given page
  830. {
  831. my $_F_ = &sed_slash_key(@_);
  832. for my $x (grep {/<$Q='[u]se.'>$_F_ /} @MK_DATA) {
  833. my $info = $x;
  834. $info =~ s/<$Q='[u]se.'>[^ ]* //; $info =~ s|<$QX>||;
  835. return $info;
  836. }
  837. }
  838. sub DC_selected # not really a DC title (shall we use alternative ?)
  839. {
  840. # each document might want to highlight the currently selected item
  841. my $short=&site_get_selected($F);
  842. if ($short) {
  843. &DC_meta ("title.selected", $short);
  844. }
  845. }
  846. sub info_get_entry_selected
  847. {
  848. return &info_get_entry("DC.title.selected");
  849. }
  850. sub site_get_rootsections # return all sections from root of nav tree
  851. {
  852. my @OUT;
  853. for (grep {/<$Q='[u]se1'>/} @MK_DATA) {
  854. my $x = $_;
  855. $x =~ s/<$Q='[u]se.'>([^ ]*) .*/$1/;
  856. push @OUT, $x;
  857. }
  858. return @OUT;
  859. }
  860. sub site_get_sectionpages # return all children pages in the given section
  861. {
  862. my $_F_=&sed_slash_key(@_);
  863. my @OUT = ();
  864. for (grep {/^<$Q='sect'>[^ ]* $_F_$/} @MK_DATA) {
  865. my $x = $_;
  866. $x =~ s/^<$Q='sect'>//; $x =~ s/ .*//; $x =~ s|<$QX>||;
  867. push @OUT, $x;
  868. }
  869. return @OUT;
  870. }
  871. sub site_get_subpages # return all page children of given page
  872. {
  873. my $_F_=&sed_slash_key(@_);
  874. my @OUT = ();
  875. for (grep {/^<$Q='node'>[^ ]* $_F_<[^<>]*>$/} @MK_DATA) {
  876. my $x = $_;
  877. $x =~ s/^<$Q='node'>//; $x =~ s/ .*//; $x =~ s|<$QX>||;
  878. push @OUT, $x;
  879. }
  880. return @OUT;
  881. }
  882. sub site_get_parentpage # ret parent page for given page (".." for sections)
  883. {
  884. my $_F_=&sed_slash_key(@_);
  885. for (grep {/^<$Q='node'>$_F_ /} @MK_DATA) {
  886. my $x = $_;
  887. $x =~ s/^<$Q='node'>[^ ]* //; $x =~ s|<$QX>||;
  888. return $x;
  889. }
  890. }
  891. sub DX_alternative # detect wether page asks for alternative style
  892. { # which is generally a shortpage variant
  893. my ($U,$Z) = @_;
  894. my $x=&mksite_magic_option("alternative",$U);
  895. $x =~ s/^ *//; $x =~s/ .*//;
  896. if ($x) {
  897. &DX_text ("alternative", $x);
  898. }
  899. }
  900. sub info2head_sed # append alternative handling script to $HEAD
  901. {
  902. my @OUT = ();
  903. my $have=&info_get_entry("alternative");
  904. if ($have) {
  905. push @OUT, "/<!--mksite:alternative:$have .*-->/ && do {";
  906. push @OUT, "s/<!--mksite:alternative:$have( .*)-->/\$1/";
  907. push @OUT, "$sed_add \$_; last; };";
  908. }
  909. return @OUT;
  910. }
  911. sub info2body_sed # append alternative handling script to $BODY
  912. {
  913. my @OUT = ();
  914. my $have=&info_get_entry("alternative");
  915. if ($have) {
  916. push @OUT, "s/<!--mksite:alternative:$have( .*)-->/\$1/";
  917. }
  918. return @OUT;
  919. }
  920. sub bodymaker_for_sectioninfo
  921. {
  922. if ($sectioninfo eq "no") { return ""; }
  923. my $_x_="<!--mksite:sectioninfo::-->";
  924. my $_q_="([^<>]*[$AX][^<>]*)";
  925. $_q_="[ ][ ]*$sectioninfo([ ])" if $sectioninfo ne " ";
  926. my @OUT = ();
  927. push @OUT, "s|(^<[hH][$NN][ >].*</[hH][$NN]>)$_q_|\$1$_x_\$2|";
  928. push @OUT, "/$_x_/ and s|^|<table width=\"100%\"><tr valign=\"bottom\"><td>|";
  929. push @OUT, "/$_x_/ and s|</[hH][$NN]>|&</td><td align=\"right\"><i>|";
  930. push @OUT, "/$_x_/ and s|\$|</i></td></tr></table>|";
  931. push @OUT, "s|$_x_||";
  932. return @OUT;
  933. }
  934. sub fast_href # args "$FILETOREFERENCE" "$FROMCURRENTFILE:$F"
  935. { # prints path to $FILETOREFERENCE href-clickable in $FROMCURRENTFILE
  936. # if no subdirectoy then output is the same as input $FILETOREFERENCE
  937. my ($T,$R,$Z) = @_;
  938. my $S=&back_path ($R);
  939. if (not $S) {
  940. return $T;
  941. } else {
  942. my $t=$T;
  943. $t =~ s/^ *$//; $t =~ s/^\/.*//;
  944. $t =~ s/^[.][.].*//; $t =~ s/^\w*:.*//;
  945. if (not $t) { # don't move any in the pattern above
  946. return $T;
  947. } else {
  948. return "$S$T"; # prefixed with backpath
  949. }
  950. }
  951. }
  952. sub make_back_path # "$FILE"
  953. {
  954. my ($R,$Z) = @_;
  955. my $S=&back_path ($R);
  956. my @OUT = ();
  957. return @OUT if $S !~ /^\.\./;
  958. push @OUT, "s|(<[^<>]*\\shref=\\\")(\\w[^<>:]*\\\"[^<>]*>)|\$1$S\$2|g;";
  959. push @OUT, "s|(<[^<>]*\\ssrc=\\\")(\\w[^<>:]*\\\"[^<>]*>)|\$1$S\$2|g;";
  960. return @OUT;
  961. }
  962. # ============================================================== SITE MAP DATA
  963. # each entry needs atleast a list-title, a long-title, and a list-date
  964. # these are the basic information to be printed in the sitemap file
  965. # where it is bound the hierarchy of sect/subsect of the entries.
  966. sub site_map_list_title # $file $text
  967. {
  968. my ($U,$V,$Z) = @_; chomp($U);
  969. push @MK_DATA, "<$Q='list'>$U ".trimm($V)."<$QX>";
  970. }
  971. sub info_map_list_title # $file $text
  972. {
  973. my ($U,$V,$Z) = @_; chomp($U);
  974. push @{$DATA{$U}}, "<$Q='list'>".trimm($V)."<$QX>";
  975. }
  976. sub site_map_long_title # $file $text
  977. {
  978. my ($U,$V,$Z) = @_; chomp($U);
  979. push @MK_DATA, "<$Q='long'>$U ".trimm($V)."<$QX>";
  980. }
  981. sub info_map_long_title # $file $text
  982. {
  983. my ($U,$V,$Z) = @_; chomp($U);
  984. push @{$DATA{$U}}, "<$Q='long'>".trimm($V)."<$QX>";
  985. }
  986. sub site_map_list_date # $file $text
  987. {
  988. my ($U,$V,$Z) = @_; chomp($U);
  989. push @MK_DATA, "<$Q='date'>$U ".trimm($V)."<$QX>";
  990. }
  991. sub info_map_list_date # $file $text
  992. {
  993. my ($U,$V,$Z) = @_; chomp($U);
  994. push @{$DATA{$U}}, "<$Q='date'>".trimm($V)."<$QX>";
  995. }
  996. sub site_get_list_title
  997. {
  998. my ($U,$V,$Z) = @_;
  999. for (@MK_DATA) { if (m|^<$Q='list'>$U (.*)<$QX>|) { return $1; } } return "";
  1000. }
  1001. sub site_get_long_title
  1002. {
  1003. my ($U,$V,$Z) = @_;
  1004. for (@MK_DATA) { if (m|^<$Q='long'>$U (.*)<$QX>|) { return $1; } } return "";
  1005. }
  1006. sub site_get_list_date
  1007. {
  1008. my ($U,$V,$Z) = @_;
  1009. for (@MK_DATA) { if (m|^<$Q='date'>$U (.*)<$QX>|) { return $1; } } return "";
  1010. }
  1011. sub siteinfo2sitemap# generate <name><page><date> addon sed scriptlet
  1012. { # the resulting script will act on each item/line
  1013. # containing <!--"filename"--> and expand any following
  1014. # reference of <!--name--> or <!--date--> or <!--long-->
  1015. my ($INP,$Z) = @_ ; $INP= \@MK_DATA if not $INP;
  1016. my @OUT = ();
  1017. my $_list_=
  1018. sub{"s|(<!--\\\"$1\\\"-->.*)<name [^<>]*>.*</name>|\$1<name href=\\\"$1\\\">$2</name>|"};
  1019. my $_date_=
  1020. sub{"s|(<!--\\\"$1\\\"-->.*)<date>.*</date>|\$1<date>$2</date>|"};
  1021. my $_long_=
  1022. sub{"s|(<!--\\\"$1\\\"-->.*)<long>.*</long>|\$1<long>$2</long>|"};
  1023. for (@$INP) {
  1024. my $info = $_;
  1025. $info =~ s:<$Q='list'>([^ ]*) (.*)<$QX>:&$_list_:e;
  1026. $info =~ s:<$Q='date'>([^ ]*) (.*)<$QX>:&$_date_:e;
  1027. $info =~ s:<$Q='long'>([^ ]*) (.*)<$QX>:&$_long_:e;
  1028. $info =~ /^s\|/ || next;
  1029. push @OUT, $info;
  1030. }
  1031. return @OUT;
  1032. }
  1033. sub make_multisitemap
  1034. { # each category gets its own column along with the usual entries
  1035. my ($INPUTS,$Z)= @_ ; $INPUTS=\@MK_DATA if not $INPUTS;
  1036. @MK_SITE = &siteinfo2sitemap(); # have <name><long><date> addon-sed
  1037. my @OUT = ();
  1038. my $_form_= sub{"<!--\"$2\"--><!--use$1--><long>$3</long><!--end$1-->"
  1039. ."<br><name href=\"$2\">$3</name><date>......</date>" };
  1040. my $_tiny_="small><small><small" ; my $_tinyX_="small></small></small ";
  1041. my $_tabb_="<br><$_tiny_> </$_tinyX_>" ; my $_bigg_="<big> </big>";
  1042. push @OUT, "<table width=\"100%\"><tr><td> ".$n;
  1043. for (grep {/<$Q='[Uu]se.'>/} @$INPUTS) {
  1044. my $x = $_;
  1045. $x =~ />\w\w\w\w*:/ and next; # name: http: ftp: mailto: ...
  1046. $x =~ s|<$Q='[Uu]se(.)'>([^ ]*) (.*)<$QX>|&$_form_|e;
  1047. $x = &eval_MK_LIST("multisitemap", $x, @MK_SITE);
  1048. $x =~ /<name/ or next;
  1049. $x =~ s|<!--[u]se1-->|</td><td valign=\"top\"><b>|;
  1050. $x =~ s|<!--[e]nd1-->|</b>|;
  1051. $x =~ s|<!--[u]se2-->|<br>|;
  1052. $x =~ s|<!--[u]se.-->|<br>|; $x =~ s/<!--[^<>]*-->/ /g;
  1053. $x =~ s|<name |<$_tiny_><a |; $x =~ s|</name>||;
  1054. $x =~ s|<date>|<small style="date">|;
  1055. $x =~ s|</date>|</small></a><br></$_tinyX_>|;
  1056. $x =~ s|<long>|<!--long-->|;
  1057. $x =~ s|</long>|<!--/long-->|;
  1058. chomp $x;
  1059. push @OUT, $x.$n;
  1060. }
  1061. push @OUT, "</td><tr></table>".$n;
  1062. return @OUT;
  1063. }
  1064. sub make_listsitemap
  1065. { # traditional - the body contains a list with date and title extras
  1066. my ($INPUTS,$Z)= @_ ; $INPUTS=\@MK_DATA if not $INPUTS;
  1067. @MK_SITE = &siteinfo2sitemap(); # have <name><long><date> addon-sed
  1068. my @OUT = ();
  1069. my $_form_=sub{
  1070. "<!--\"$2\"--><!--use$1--><name href=\"$2\">$3</name><date>......</date><long>$3</long>"};
  1071. my $_tabb_="<td>\&nbsp\;</td>";
  1072. push @OUT, "<table cellspacing=\"0\" cellpadding=\"0\">".$n;
  1073. my $xx;
  1074. for $xx (grep {/<$Q='[Uu]se.'>/} @$INPUTS) {
  1075. my $x = "".$xx;
  1076. $x =~ />\w\w\w\w*:/ and next;
  1077. $x =~ s|<$Q='[Uu]se(.)'>([^ ]*) (.*)<$QX>|&$_form_|e;
  1078. $x = &eval_MK_LIST("listsitemap", $x, @MK_SITE);
  1079. $x =~ /<name/ or next;
  1080. $x =~ s|<!--[u]se(1)-->|<tr class=\"listsitemap$1\"><td>*</td>|;
  1081. $x =~ s|<!--[u]se(2)-->|<tr class=\"listsitemap$1\"><td>-</td>|;
  1082. $x =~ s|<!--[u]se(.)-->|<tr class=\"listsitemap$1\"><td> </td>|;
  1083. $x =~ /<tr.class=\"listsitemap3\">/ and $x =~ s|(<name [^<>]*>)|$1- |;
  1084. $x =~ s|<!--[^<>]*-->| |g;
  1085. $x =~ s|<name href=\"name:sitemap:|<name href=\"|;
  1086. $x =~ s|<name |<td><a |; $x =~ s|</name>|</a></td>$_tabb_|;
  1087. $x =~ s|<date>|<td><small style="date">|;
  1088. $x =~ s|</date>|</small></td>$_tabb_|;
  1089. $x =~ s|<long>|<td><em><!--long-->|;
  1090. $x =~ s|</long>|<!--/long--></em></td></tr>|;
  1091. push @OUT, $x.$n;
  1092. }
  1093. for $xx (grep {/<$Q='[u]se.'>/} @$INPUTS) {
  1094. my $x = $xx;
  1095. $x =~ s/<$Q='[u]se.'>name:sitemap://; $x =~ s|<$QX>||; $x =~ s:\s*::gs;
  1096. if (-f $x) {
  1097. for (grep {/<tr.class=\"listsitemap\d\">/} source($x)) {
  1098. push @OUT, $_;
  1099. }
  1100. }
  1101. }
  1102. push @OUT, "</table>".$n;
  1103. return @OUT;
  1104. }
  1105. my $_xi_include_=
  1106. "<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" parse=\"xml\"";
  1107. sub make_xmlsitemap
  1108. { # traditional - the body contains a list with date and title extras
  1109. my ($INPUTS,$Z)= @_ ; $INPUTS=\@MK_DATA if not $INPUTS;
  1110. @MK_SITE = &siteinfo2sitemap(); # have <name><long><date> addon-sed
  1111. my @OUT = ();
  1112. my $_form_=sub{"<!--\"$2\"--><name href=\"$2\">$3</name>"};
  1113. my $xx;
  1114. for $xx (grep {/<$Q='[Uu]se.'>/} @$INPUTS) {
  1115. my $x = "".$xx;
  1116. $x =~ />\w\w\w\w*:/ and next;
  1117. $x =~ s|<$Q='[Uu]se(.)'>([^ ]*) (.*)<$QX>|&$_form_|e;
  1118. $x = &eval_MK_LIST("listsitemap", $x, @MK_SITE);
  1119. $x =~ /<name/ or next;
  1120. $x =~ m|href="${SITEFILE}"| and next;
  1121. $x =~ m|href="${SITEFILE}l"| and next;
  1122. $x =~ s|(href="[^<>]*)\.html(")|$1.xml$2|g;
  1123. $x =~ s|.*<name|$_xi_include_$n |;
  1124. $x =~ s|>.*</name>| />|;
  1125. push @OUT, $x.$n;
  1126. }
  1127. return @OUT;
  1128. }
  1129. sub print_extension
  1130. {
  1131. my ($ARG,$Z)= @_ ; $ARG=$o{print} if not $ARG;
  1132. if ($ARG =~ /^([.-])/) {
  1133. return $ARG;
  1134. } else {
  1135. return ".print";
  1136. }
  1137. }
  1138. sub from_sourcefile
  1139. {
  1140. my ($U,$Z) = @_;
  1141. if (-f $U) {
  1142. return $U;
  1143. } elsif (-f "$o{src_dir}/$U") {
  1144. return "$o{src_dir}/$U";
  1145. } else {
  1146. return $U;
  1147. }
  1148. }
  1149. sub html_sourcefile # generally just cut away the trailing "l" (ell)
  1150. { # making "page.html" argument into "page.htm" return
  1151. my ($U,$Z) = @_;
  1152. my $_SRCFILE_=$U; $_SRCFILE_ =~ s/l$//;
  1153. my $_XMLFILE_=$U; $_XMLFILE_ =~ s/\.html$/.dbk/;
  1154. if (-f $_SRCFILE_) {
  1155. return $_SRCFILE_;
  1156. } elsif (-f $_XMLFILE_) {
  1157. return $_XMLFILE_;
  1158. } elsif (-f "$o{src_dir}/$_SRCFILE_") {
  1159. return "$o{src_dir}/$_SRCFILE_";
  1160. } elsif (-f "$o{src_dir}/$_XMLFILE_") {
  1161. return "$o{src_dir}/$_XMLFILE_";
  1162. } else {
  1163. return ".//$_SRCFILE_";
  1164. }
  1165. }
  1166. sub html_printerfile_sourcefile
  1167. {
  1168. my ($U,$Z) = @_;
  1169. if (not $printerfriendly) {
  1170. $U =~ s/l\$//; return $U;
  1171. } else {
  1172. my $_ext_=&sed_slash_key(&print_extension($printerfriendly));
  1173. $U =~ s/l\$//; $U =~ s/$_ext_([.][\w]*)$/$1/; return $U;
  1174. }
  1175. }
  1176. sub fast_html_printerfile {
  1177. my ($U,$V,$Z) = @_;
  1178. my $x=&html_printerfile($U) ; return basename($x);
  1179. # my $x=&html_printerfile($U) ; return &fast_href($x,$V);
  1180. }
  1181. sub html_printerfile # generate the printerfile for a given normal output
  1182. {
  1183. my ($U,$Z) = @_;
  1184. my $_ext_=&esc(&print_extension($printerfriendly));
  1185. $U =~ s/([.][\w]*)$/$_ext_$1/; return $U; # index.html -> index.print.html
  1186. }
  1187. sub make_printerfile_fast # generate s/file.html/file.print.html/ for hrefs
  1188. { # we do that only for the $FILELIST
  1189. my ($U,$Z) = @_;
  1190. my $ALLPAGES=$U;
  1191. my @OUT = ();
  1192. for my $p (@$ALLPAGES) {
  1193. my $a=&sed_slash_key($p);
  1194. my $b=&html_printerfile($p);
  1195. if ($b ne $p) {
  1196. $b =~ s:/:\\/:g;
  1197. push @OUT,
  1198. "s/<a href=\\\"$a\\\"([^<>])*>/<a href=\\\"$b\\\"\$1>/;";
  1199. }
  1200. }
  1201. return @OUT;
  1202. }
  1203. sub echo_printsitefile_style
  1204. {
  1205. my $_bold_="text-decoration : none ; font-weight : bold ; ";
  1206. return " <style>"
  1207. ."$n a:link { $_bold_ color : #000060 ; }"
  1208. ."$n a:visited { $_bold_ color : #000040 ; }"
  1209. ."$n body { background-color : white ; }"
  1210. ."$n </style>"
  1211. ."$n";
  1212. }
  1213. sub make_printsitefile_head # $sitefile
  1214. {
  1215. my $MK_STYLE = &echo_printsitefile_style();
  1216. my @OUT = ();
  1217. for (source($SITEFILE)) {
  1218. if (/<head>/) { push @OUT, $_;
  1219. push @OUT, $MK_STYLE; next; }
  1220. if (/<title>/) { push @OUT, $_; next; }
  1221. if (/<\/head>/) { push @OUT, $_; next; }
  1222. if (/<body>/) { push @OUT, $_; next; }
  1223. if (/<link [^<>]*rel=\"shortcut icon\"[^<>]*>/) {
  1224. push @OUT, $_; next;
  1225. }
  1226. }
  1227. return @OUT;
  1228. }
  1229. # ------------------------------------------------------------------------
  1230. # The printsitefile is a long text containing html href markups where
  1231. # each of the href lines in the file is being prefixed with the section
  1232. # relation. During a secondary call the printsitefile can grepp'ed for
  1233. # those lines that match a given output fast-file. The result is a
  1234. # navigation header with 1...3 lines matching the nesting level
  1235. # these alt-texts will be only visible in with a text-mode browser:
  1236. my $printsitefile_square="width=\"8\" height=\"8\" border=\"0\"";
  1237. my $printsitefile_img_1="<img alt=\"|go text:\" $printsitefile_square />";
  1238. my $printsitefile_img_2="<img alt=\"||topics:\" $printsitefile_square />";
  1239. my $printsitefile_img_3="<img alt=\"|||pages:\" $printsitefile_square />";
  1240. my $_SECT="mksite:sect:";
  1241. sub echo_current_line # $sect $extra
  1242. {
  1243. # add the prefix which is used by select_in_printsitefile to cut out things
  1244. my ($N,$M,$Z) = @_;
  1245. return "<!--$_SECT\"$N\"-->$M";
  1246. }
  1247. sub make_current_entry # $sect $file ## requires $MK_SITE
  1248. {
  1249. my ($S,$R,$Z) = @_;
  1250. my $RR=&sed_slash_key($R);
  1251. my $sep=" - " ; my $_left_=" [ " ; my $_right_=" ] ";
  1252. my $name = site_get_list_title($R);
  1253. $_ = &echo_current_line ("$S", "<a href=\"$R\">$name</a>$sep");
  1254. if ($R eq $S) {
  1255. s/<a href/$_left_$&/;
  1256. s/<\/a>/$&$_right_/;
  1257. }
  1258. return $_;
  1259. }
  1260. sub echo_subpage_line # $sect $extra
  1261. {
  1262. my ($N,$M,$Z) = @_;
  1263. return "<!--$_SECT*:\"$N\"-->$M";
  1264. }
  1265. sub make_subpage_entry
  1266. {
  1267. my ($S,$R,$Z) = @_;
  1268. my $RR=&sed_slash_key($R);
  1269. my $sep=" - " ;
  1270. my $name = site_get_list_title($R);
  1271. $_ = &echo_subpage_line ("$S", "<a href=\"$R\">$name</a>$sep");
  1272. return $_;
  1273. }
  1274. sub make_printsitefile
  1275. {
  1276. # building the printsitefile looks big but its really a loop over sects
  1277. my ($INPUTS,$Z) = @_; $INPUTS=\@MK_DATA if not $INPUTS;
  1278. @MK_SITE = &siteinfo2sitemap(); # have <name><long><date> addon-sed
  1279. savelist(\@MK_SITE,"SITE");
  1280. my @OUT = &make_printsitefile_head ($SITEFILE);
  1281. my $sep=" - " ;
  1282. my $_sect1=
  1283. "<a href=\"#.\" title=\"section\">$printsitefile_img_1</a> ||$sep";
  1284. my $_sect2=
  1285. "<a href=\"#.\" title=\"topics\">$printsitefile_img_2</a> ||$sep";
  1286. my $_sect3=
  1287. "<a href=\"#.\" title=\"pages\">$printsitefile_img_3</a> ||$sep";
  1288. my $_SECT1="mksite:sect1";
  1289. my $_SECT2="mksite:sect2";
  1290. my $_SECT3="mksite:sect3";
  1291. @MK_SECT1 = &site_get_rootsections();
  1292. # round one - for each root section print a current menu
  1293. for my $r (@MK_SECT1) {
  1294. push @OUT, &echo_current_line ("$r", "<!--$_SECT1:A--><br>$_sect1");
  1295. for my $s (@MK_SECT1) {
  1296. push @OUT, &make_current_entry ("$r", "$s");
  1297. }
  1298. push @OUT, &echo_current_line ("$r", "<!--$_SECT1:Z-->");
  1299. }
  1300. # round two - for each subsection print a current and subpage menu
  1301. for my $r (@MK_SECT1) {
  1302. @MK_SECT2 = &site_get_subpages ("$r");
  1303. for my $s (@MK_SECT2) {
  1304. push @OUT, &echo_current_line ("$s", "<!--$_SECT2:A--><br>$_sect2");
  1305. for my $t (@MK_SECT2) {
  1306. push @OUT, &make_current_entry ("$s", "$t");
  1307. } # "$t"
  1308. push @OUT, &echo_current_line ("$s", "<!--$_SECT2:Z-->");
  1309. } # "$s"
  1310. my $_have_children_="";
  1311. for my $t (@MK_SECT2) {
  1312. if (not $_have_children_) {
  1313. push @OUT, &echo_subpage_line ("$r", "<!--$_SECT2:A--><br>$_sect2"); }
  1314. $_have_children_ .= "1";
  1315. push @OUT, &make_subpage_entry ("$r", "$t");
  1316. }
  1317. if ($_have_children_) {
  1318. push @OUT, &echo_subpage_line ("$r", "<!--$_SECT2:Z-->"); }
  1319. } # "$r"
  1320. # round three - for each subsubsection print a current and subpage menu
  1321. for my $r (@MK_SECT1) {
  1322. @MK_SECT2 = &site_get_subpages ("$r");
  1323. for my $s (@MK_SECT2) {
  1324. @MK_SECT3 = &site_get_subpages ("$s");
  1325. for my $t (@MK_SECT3) {
  1326. push @OUT, &echo_current_line ("$t", "<!--$_SECT3:A--><br>$_sect3");
  1327. for my $u (@MK_SECT3) {
  1328. push @OUT, &make_current_entry ("$t", "$u");
  1329. } # "$t"
  1330. push @OUT, &echo_current_line ("$t", "<!--$_SECT3:Z-->");
  1331. } # "$t"
  1332. my $_have_children_="";
  1333. for my $u (@MK_SECT3) {
  1334. if (not $_have_children_) {
  1335. push @OUT, &echo_subpage_line ("$s", "<!--$_SECT3:A--><br>$_sect3"); }
  1336. $_have_children_ .= "1";
  1337. push @OUT, &make_subpage_entry ("$s", "$u");
  1338. }
  1339. if ($_have_children_) {
  1340. push @OUT, &echo_subpage_line ("$s", "<!--$_SECT3:Z-->"); }
  1341. } # "$s"
  1342. } # "$r"
  1343. push @OUT, "<a name=\".\"></a>";
  1344. push @OUT, "</body></html>";
  1345. savelist(\@OUT,"FORM");
  1346. return @OUT;
  1347. }
  1348. # create a selector that can grep a printsitefile for the matching entries
  1349. sub select_in_printsitefile # arg = "page" : return to stdout >> $P.$HEAD
  1350. {
  1351. my ($N,$Z) = @_;
  1352. my $_selected_="$N" ; $_selected_="$F" if not $_selected_;
  1353. my $_section_=&sed_slash_key($_selected_);
  1354. my @OUT = ();
  1355. push @OUT, "s/^<!--$_SECT\\\"$_section_\\\"-->//;"; # sect3
  1356. push @OUT, "s/^<!--$_SECT\[*\]:\\\"$_section_\\\"-->//;"; # children
  1357. $_selected_=&site_get_parentpage($_selected_);
  1358. $_section_=&sed_slash_key($_selected_);
  1359. push @OUT, "s/^<!--$_SECT\\\"$_section_\\\"-->//;"; # sect2
  1360. $_selected_=&site_get_parentpage($_selected_);
  1361. $_section_=&sed_slash_key($_selected_);
  1362. push @OUT, "s/^<!--$_SECT\\\"$_section_\\\"-->//;"; # sect1
  1363. push @OUT, "/^<!--$_SECT\\\"[^\\\"]*\\\"-->/ and next;";
  1364. push @OUT, "/^<!--$_SECT\[*\]:\\\"[^\\\"]*\\\"-->/ and next;";
  1365. push @OUT, "s/^<!--mksite:sect[$NN]:[$AZ]-->//;";
  1366. return @OUT;
  1367. }
  1368. sub body_for_emailfooter
  1369. {
  1370. return "" if $emailfooter eq "no";
  1371. my $_email_=$emailfooter; $_email_ =~ s|[?].*||;
  1372. my $_dated_=&info_get_entry("updated");
  1373. return "<hr><table border=\"0\" width=\"100%\"><tr><td>"
  1374. ."$n"."<a href=\"mailto:$emailfooter\">$_email_</a>"
  1375. ."$n"."</td><td align=\"right\">"
  1376. ."$n"."$_dated_</td></tr></table>"
  1377. ."$n";
  1378. }
  1379. # =================================================================== CSS
  1380. # There was another project to support sitemap build from xml files.
  1381. # The source format was using .dbk+xml with embedded references to .css
  1382. # files for visual preview in a browser. An docbook xml file with semantic
  1383. # outlines is far better suited for quality documentation than any html
  1384. # source. It happens that the xml/css support in browsers is still not
  1385. # very portable - especially embedded css style blocks are a nightmare.
  1386. # Instead we (a) grab all non-html xml markup tags (b) grab all referenced
  1387. # css stylesheets (c) cut out css defs from [b] that are known by [a] and
  1388. # (d) append those to the <style> tag in the output html file as well as
  1389. # (e) reformatting the defs as well as markups from tags to tag classes.
  1390. # Input dbk/htm
  1391. # <?xml-stylesheet type="text/css" href="html.css" ?> <!-- dbk/xml -->
  1392. # <link rel="stylesheet" type="text/css" href="sdocbook.css" /> <!-- xhtml -->
  1393. # <article><para>
  1394. # Using some <command>exe</command>
  1395. # </para></article

Large files files are truncated, but you can click here to view the full file