Re: Faq format
Steffen Daode Nurpmeso <[email protected]>
| Newsgroups | gmane.os.openbsd.www |
|---|---|
| Message-ID | <[email protected]> |
Niko Gonzales <[email protected]> wrote: |Thanks for the advice; due to the consistency of the source html I figured |y'all used some sort of automated tool to generate it - as always I am |impressed at the quality that the Openbsd community produces. |[.] |Maybe I'll go with a customized markdown-to-html script or just roll |guerrilla-vi style like you - thanks for the information everyone! | |Niko |Hello! Don't be so hard on yourself - I enjoy reading openbsd |documentation more than any other . I'll look into writing my own |formatter that spits out html similar to your faq then - I am not |so worried about compliance and perfection in the DOM than I am |about making simple and easy-to-read webpages. So long and thanks |for that bit of perl! Well really - i didn't want to be hard to you! So i've depersonalized the brute simple thing (be warned a bit) a bit and append it below; that in conjunction with some keyboard :map pings as of vim(1) should give you a somewhat comfortably non-numb starter for nice static webpages. I hope it's ok to post it here, though it's unrelated to OpenBSD. Howto use it: 1. Be warned - it's brute simple. It is not ment for sophisticated web programming with a deeply nested tagsoup, and thus has never been tested with that. 2. A subdirectory base/ should be present for images, styles and scripts and other things which should be copied unmodified. 3. A subdirectory html/ should consist of files which should be expanded. I.e., copy the template.* therein under whatever names, edit them and then.. 4. Run build.sh to expand the stuff and copy it into $TMPDIR/public-html. There is some dumb logic in there which will copy to ~/public-html or ~/Sites (Mac OS X); for this to be used, change the line TARGETDIR="$TMPDIR/public-web" to #TARGETDIR="$TMPDIR/public-web" 5. For more commands and such, edit expand-html.pl and extend it for your purpose. Fine. --steffen Forza Figa! diff --git a/web/build.sh b/web/build.sh new file mode 100755 index 0000000..cfed187 --- /dev/null +++ b/web/build.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# Extremely simple in respect to path building! +# Public Domain. + +# Relative paths.. +SRCDIR=. +TARGETDIR="$TMPDIR/public-web" + +if [ x"$TARGETDIR" = x ]; then + if [ -d "$HOME/public_html" ]; then + TARGETDIR="$HOME/public_html" + elif [ -d "$HOME/Sites" ]; then + TARGETDIR="$HOME/Sites" + else + echo 'No target directory found' + exit 1 + fi + echo "TARGETDIR was not set - auto-detected $TARGETDIR" +fi + +set -e +set -u + +if [ ! -d "$TARGETDIR" ]; then + echo "TARGETDIR ($TARGETDIR) does not exist - sleep 3; mkdir -p" + sleep 3; mkdir -p "$TARGETDIR" +fi + +cd $SRCDIR + +KEPT=0 +REFRESHED=0 +echo +echo "Checking base files: <$SRCDIR/base>" +cd base +for i in *.*; do + echo " - Action on <$i> ... \c" + if [ ! -r $i ]; then + echo "READ-ERROR: SKIP" + continue + fi + target="$TARGETDIR/$i" + + if [ ! -f $target ] || [ $target -ot $i ]; then + echo 'refresh' + cp -X -f $i $target + chmod o+r $target + REFRESHED=$(( $REFRESHED + 1 )) + else + echo 'keep' + KEPT=$(( $KEPT + 1 )) + fi +done +cd .. +echo "$KEPT files were up to date." +echo "$REFRESHED files have been updated." + +KEPT=0 +REFRESHED=0 +echo +echo "Processing HTML" +cd html +for i in *.*; do + echo " - Action on <$i> ... \c" + if [ ! -r $i ]; then + echo "READ-ERROR: SKIP" + continue + fi + target="$TARGETDIR/$i" + + if [ ! -f $target ] || [ $target -ot $i ]; then + echo 'refresh' + perl -- "../expand-html.pl" < "$i" > $target + chmod o+r $target + REFRESHED=$(( $REFRESHED + 1 )) + else + echo 'keep' + KEPT=$(( $KEPT + 1 )) + fi +done +cd .. +echo "$KEPT files were up to date." +echo "$REFRESHED files have been updated." + +exit 0 +# vim:set fenc=utf-8 syntax=sh ts=4 sts=4 sw=4 et tw=79: diff --git a/web/expand-html.pl b/web/expand-html.pl new file mode 100644 index 0000000..42ae38e --- /dev/null +++ b/web/expand-html.pl @@ -0,0 +1,299 @@ +#!/usr/bin/perl -w +# Extremely simple... Reads from <STDIN>, dumps to <STDOUT>. +# Public Domain. +# +# TODO: no interlocked conditionals, no auto-link generation or -verify... +# TODO: Problems: +# - Recursive ifn?def..fi not yet implemented. +# - No if0 yet. +# - This is not possible: +# XML = <?hreft "http://www.w3.org;<?ac XML?>"?> +# Only this will do +# XML = <?hreft "http://www.w3.org;<acronym>XML</acronym>"?> + +# Default variables, most adjusted in preface_end().. +my %HASH = ( + AUTHOR => 'Your Name', + AUTHOR_AND_EMAIL => 'Your Name <YOUR@MAIL>', + AUTHOR_AND_EMAIL_RAW => 'Your Name, YOUR@MAIL', + #STREET => 'Außerhalb 42', + #CITY => 'CH-4221 Ancona', + #PHONE => '##49 (0)6151 / 101010', + #FAX => '##49 (0)6151 / 1010', + WEB => 'YOUR-WEB', + MAIL => 'YOUR@MAIL', + COPY_DATE_SPEC => '1997 - 2012', + # + WWW => '<strong class="_web" title="WEB!">∞</strong>', + NAVI_UP => '⇑', + NAVI_FIRST => '⇐', + NAVI_LAST => '⇒', + NAVI_PREV => '←', + NAVI_NEXT => '→', + NAVI_PTOP => '<a class="_top" href="#_top" title="Page-Top">↑</a>', + PTOP_NAVI => '<div class="_topdown"><p><a class="_topdownmove" ' . + 'href="#_top" title="Page-Top">↑</a> ' . + '<a class="_topdownmove" href="#_bottom" ' . + 'title="Page-Bottom">↓</a></p></div>', + CVS => undef, + # Don't touch the rest directly, use <?var ?> PI's ... + TITLE => undef, + DESC => undef, + KEYWORDS => undef, + TOPMENU => undef, + LAST_MODIFIED => undef, + HEAD_INJECT => '' +); + +my @sb; +my $line; +my $last_line = undef; +my $FHDL; +my $begin_end = 0; # In between <?begin?> .. <?end?> ? +my $raw = 0; # In a <?raw?> PI? +my $in_iffi = 0; # In a <?if?> +my ($i,$j); + +# Timestamp; do that first not in preface_end +(@sb = stat(STDIN)) || die "Cannot stat STDIN"; +@sb = gmtime($sb[9]); +$i = sprintf("%04d-%02d-%02dT%02d:%02d:%02d", + $sb[5]+1900, $sb[4]+1, $sb[3], $sb[2], $sb[1], $sb[0]); +$HASH{'LAST_MODIFIED'} = $i; + +# Everything until <?begin?> +while ($line = <STDIN>) { + next if line_adjust_drop(); + last if preface_line(); +} +preface_end(); + +# Header +open(FD, "<../header") || die $^E; + $FHDL = *FD; + process_fhdl(); +close(FD); + +# Everything until <?end?> +$FHDL = *STDIN; +$begin_end = 1; +process_fhdl(); +$begin_end = 0; + +# Footer +open(FD, "<../footer") || die $^E; + $FHDL = *FD; + process_fhdl(); +close(FD); + +exit(0); + +sub line_adjust_drop { + $line =~ s/\s+$//o; + + # <?raw?> lines are always passed through unchanged + return 0 if $raw; + # Empty lines are discarded + return 1 if $line =~ /^\s*$/o; + # Perlish comment lines are discarded + return 1 if $line =~ /^\s*#/o; + + $line =~ s/^\s+//o; + $line =~ s/\s+/ /o; + return 0; +} + +sub preface_line { + return 1 if $line =~ /<\?begin\?>/o; + + # Special TOPMENU? + if ($line =~ /^\s*TOPMENU/o) { + print STDERR "TOPMENU already set\n" if $HASH{TOPMENU}; + my $str; + while ($line = <STDIN>) { + $line =~ s/^\s+//o; + $line =~ s/\s+$//o; + $line =~ s/\s+/ /o; + last if $line eq 'TOPMENU'; + $str .= "<li>$line </li>"; + } + $HASH{TOPMENU} = $str; + # Variable assignments + } elsif ($line =~ /^\s*(\w+)\s*=\s*(.*)$/o) { + print STDERR "Variable $1 already set\n" if $HASH{$1}; + $HASH{$1} = $2; + } else { + die "Unknown directive, 1.: $line"; + } + return 0; +} + +sub preface_end { + unless (defined $HASH{TITLE}) { + print STDERR "TITLE variable not set!!\n"; + $HASH{TITLE} = 'TITLE NOT SET!!'; + } + $HASH{PACK_LEVEL} = 1 unless defined $HASH{PACK_LEVEL}; +} + +sub process_fhdl { + while ($line = <$FHDL>) { + next if line_adjust_drop(); + last if line_conversion(); + } + print($last_line, "\x0A") if $last_line; + $last_line = undef; + die "Conditional still open!" if $in_iffi != 0; +} + +sub line_conversion { + if ($line =~ /<\?.+\?>/o) { + my $i = pi_expansion(); + return 1 if $i > 0; + return 0 if $i < 0; + } + + # German umlauts and sharp-s + $line =~ s/\xC3\xA4/ä/og; + $line =~ s/\xC3\x84/Ä/og; + $line =~ s/\xC3\xB6/ö/og; + $line =~ s/\xC3\x96/Ö/og; + $line =~ s/\xC3\xBC/ü/og; + $line =~ s/\xC3\x9C/Ü/og; + $line =~ s/\xC3\x9F/ß/og; + + if ($raw) { + print($last_line, "\x0A") if $last_line; + $last_line = undef; + print $line, "\x0A"; + } else { + if ($last_line && $last_line =~ />$/ && $line =~ /^</) { + $last_line .= $line; + } else { + print($last_line, "\x0A") if $last_line; + $last_line = (length($line) > 0) ? $line : undef; + } + } + return 0; +} + +sub pi_expansion { + return 0 if index($line, '<?xml ') == 0; + my $xl = $line; + $line = ''; + + while ($xl =~ /(.*?)<\?(\w+)(?:\s+(?:(?:"([^"]*)")|([^\?]*)))?\?>(.*)/o) { + $line .= $1 if (defined $1 && length($1) > 0); + $xl = defined $5 ? $5 : ''; + $i = $2; + $j = defined $3 ? $3 : defined $4 ? $4 : '';#undef; + + # Variable? + if ($i eq 'ev') { + unless (exists $HASH{$j} && defined $HASH{$j}) { + print STDERR "ev: <$j> not set!\n"; + $i = '?'; + } else { + $i = $HASH{$j}; + } + # May contain more ev's, expand and redo! + $xl = $i . $xl; + next; + } + # Local link? + elsif ($i eq 'lref') { + $i = "<a href=\"$j\">$j</a>"; + $line .= $i; + } + # Local link with title/text? + elsif ($i eq 'lreft') { + $j =~ /(.+?);(.+)/o; + my $w = $1; + my $z = $2; + my $y = $z; + while ($y =~ s/(.*?)<\/?\w+>(.*)/$1$2/g) {;} + $i = "<a href=\"$w\" title=\"$y\">$z</a>"; + $line .= $i; + } + # Hyper link? + elsif ($i eq 'href') { + $i = "<a href=\"$j\">$HASH{WWW} $j</a>"; + $line .= $i; + } + # Hyper link with title/text? + elsif ($i eq 'hreft') { + $j =~ /(.+?);(.+)/o; + my $w = $1; + my $z = $2; + my $y = $z; + while ($y =~ s/(.*?)<\/?\w+>(.*)/$1$2/g) {;} + $i = "<a href=\"$w\" title=\"$y\">" . + "$HASH{WWW} $z</a>"; + $line .= $i; + } + # Acronym? + elsif ($i eq 'ac') { + $i = "<acronym>$j</acronym>"; + $line .= $i; + } + # Acronym with title? + elsif ($i eq 'act') { + $j =~ /(.+);(.+)/o; + $i = "<acronym title=\"$2\">$1</acronym>"; + $line .= $i; + } elsif ($i eq 'ifdef') { + die "ifdef: interlocked conditionals not supported" + if $in_iffi != 0; + $in_iffi = 1; + elsefi_skip() unless defined $HASH{$j}; + return -1; + } elsif ($i eq 'ifndef') { + die "ifdef: interlocked conditionals not supported" + if $in_iffi != 0; + $in_iffi = 1; + elsefi_skip() if defined $HASH{$j}; + return -1; + } elsif ($i eq 'else') { + # We only come here if last condition was true + elsefi_skip(); + return -1; + } elsif ($i eq 'fi') { + die "Unmatched <?fi?>" if $in_iffi == 0; + $in_iffi = 0; + return -1; + } elsif ($i eq 'raw') { + if ($j =~ /ON|on/) { $raw = 1; } + elsif ($j =~ /OFF|off/) { $raw = 0; } + else { die "Bad <?raw?>: $line"; } + return -1; + } elsif ($i eq 'include_raw') { + $j = $1 if $j =~ /^"(.*)"$/o; + open(MYFD, "<$j") || die $^E; + print $_ foreach (<MYFD>); + close MYFD; + return -1; + } elsif ($i eq 'end') { + die "<?end?> may not be used here" unless $begin_end; + return 1; + } elsif ($i eq 'cvsid') { + $line .= "<br />$HASH{CVS}" if defined $HASH{CVS}; + } else { + die "Unknown directive, 2.: $i"; + } + } + + $line .= $xl if length($xl) > 0; + return 0; +} + +sub elsefi_skip { + while ($line = <$FHDL>) { + last if $line =~ /^\s*<\?else\?>/o; + if ($line =~ /^\s*<\?fi\?>/o) { + $in_iffi = 0; + last; + } + } +} + +# vim:set fenc=utf-8 syntax=perl ts=4 sts=4 sw=4 et tw=79: diff --git a/web/footer b/web/footer new file mode 100644 index 0000000..7bdb4fa --- /dev/null +++ b/web/footer @@ -0,0 +1,34 @@ +# Public Domain. +# Keep this in sync with footer.php! +</div><div id="_bottom"> + +<div id="_bottommenu"><ul> +<li><?ev NAVI_PTOP?> </li> +<?ifdef FIRST?> +<li><a class="_first" href="<?ev FIRST?>" title="First page"><?ev NAVI_FIRST?></a> </li> +<?fi?> +<?ifdef PREV?> +<li><a class="_prev" href="<?ev PREV?>" title="Previous page"><?ev NAVI_PREV?></a> </li> +<?fi?> +<?ifdef UP?> +<li><a class="_up" href="<?ev UP?>" title="Up to higher level"><?ev NAVI_UP?></a> </li> +<?fi?> +<?ifdef NEXT?> +<li><a class="_next" href="<?ev NEXT?>" title="Next page"><?ev NAVI_NEXT?></a> </li> +<?fi?> +<?ifdef LAST?> +<li><a class="_last" href="<?ev LAST?>" title="Last page"><?ev NAVI_LAST?></a> </li> +<?fi?> +<?ifndef HOMEPAGE?> +<li><a class="_home" href="index.html" title="Homepage">Home</a> </li> +<?fi?> +</ul></div> + +<div id="_copycontact"><p> +Copyright (c) <?ev COPY_DATE_SPEC?>, + <a href="mailto:<?ev MAIL?>" title="E-Mail to <?ev MAIL?>"><?ev AUTHOR_AND_EMAIL?></a><?cvsid?> +</p></div> + +</div> +</body> +</html> diff --git a/web/header b/web/header new file mode 100644 index 0000000..45bcb9c --- /dev/null +++ b/web/header @@ -0,0 +1,66 @@ +# Public Domain. +# Keep this in sync with header.php! +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title><?ev TITLE?></title> + +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<meta name="Author" content="<?ev AUTHOR_AND_EMAIL_RAW?>" /> +<meta name="generator" content="vim and a build.sh|expand-html.pl" /> +<?ifdef DESC?> +<meta name="Description" content="<?ev DESC?>" /> +<?fi?> +<?ifdef KEYWORDS?> +<meta name="Keywords" content="<?ev KEYWORDS?>" /> +<?fi?> +<meta name="Date" content="<?ev LAST_MODIFIED?>" /> + +<link rel="stylesheet" type="text/css" href="style.css" /> + +<script type="text/javascript" src="script.js"></script> +<?ev HEAD_INJECT?></head> +<body> +<div id="_top"> + +<?ifdef CHAPTER?> +<div id="_toptitle"><?ev CHAPTER?></div> +<?else?> +<div id="_toptitle"><?ev TITLE?></div> +<?fi?> + +<div id="_topmenu"><ul> +<?ifdef FIRST?> +<li><a class="_first" href="<?ev FIRST?>" title="First page"><?ev NAVI_FIRST?></a> </li> +<?fi?> +<?ifdef PREV?> +<li><a class="_prev" href="<?ev PREV?>" title="Previous page"><?ev NAVI_PREV?></a> </li> +<?fi?> +<?ifdef UP?> +<li><a class="_up" href="<?ev UP?>" title="Up to higher level"><?ev NAVI_UP?></a> </li> +<?fi?> +<?ifdef NEXT?> +<li><a class="_next" href="<?ev NEXT?>" title="Next page"><?ev NAVI_NEXT?></a> </li> +<?fi?> +<?ifdef LAST?> +<li><a class="_last" href="<?ev LAST?>" title="Last page"><?ev NAVI_LAST?></a> </li> +<?fi?> +<?ifndef HOMEPAGE?> +<li><a class="_home" href="index.html" title="Homepage">Home</a> </li> +<?fi?> +<?ifdef TOPMENU?> +<?ev TOPMENU?> +<?fi?> +</ul> +</div> + +</div><div id="_body"> + +<div id="_title"><h<?ev PACK_LEVEL?>> +<?ifdef HEADLINE?> +<?ev HEADLINE?> +<?else?> +<?ev TITLE?> +<?fi?> +</h<?ev PACK_LEVEL?>></div> diff --git a/web/template.html b/web/template.html new file mode 100644 index 0000000..d6ba08c --- /dev/null +++ b/web/template.html @@ -0,0 +1,55 @@ +# Public Domain. +CVS = $Id$ +# Pack is about heading level (is this file a sub+section?); this value is +# trimmed and used *directly*, as in '<h<?ev PACK_LEVEL?>>'! +PACK_LEVEL = 2 +CHAPTER = Make editors slightly moist! +TITLE = Qual - Some More +HEADLINE = Qual +DESC = A Poem +KEYWORDS = Qual, Poems +COPY_DATE_SPEC = 1997 - 2012 + +# If set, will be used as target files for navigation (header,footer) +FIRST = .html +PREV = .html +UP = .html +NEXT = .html +LAST = .html + +TOPMENU + <?lreft "xy.html;Xy"?> + <?lreft "disccopy.html;Imprint and Disclaimer"?> +TOPMENU +HEAD_INJECT = <style type="text/css"><!-- --></style> + +# Define your own stuff - use via <?ev ECHO-VAR-NAME?> +C = <?ac C?> +CPP = <?ac C++?> +OPENBSD = <?hreft "http://www.openbsd.org;OpenBSD"?> +<?begin?> + +<p> + <?ev OPENBSD?>. +</p><pre> +<?raw ON?> + Everything left unexpanded + in here +<?raw OFF?> +</pre><p> + Navigation bars can be found at the top and the bottom of each page, + which provide a subset of the following symbols: + <?ev NAVI_UP?> loads the parent chapter, + <?ev NAVI_FIRST?> and <?ev NAVI_LAST?> load the first and last page of + a section, respectively, + <?ev NAVI_PREV?> and <?ev NAVI_NEXT?> load the previous/the next page; + likewise ↑ and ↓ can be used to scroll to the top and the + bottom of the currently loaded page. + Hyperlinks which refer to other sites on the internet are + <em>explicitly</em> marked (preceeded) with <?ev WWW?>. + As you can see UNICODE characters are used instead of images - + try an UTF-8 aware locale/console/browser if you have display problems. +</p> + +<?end?> +<!-- vim:set fenc=utf-8 syntax=xml ts=1 sts=1 sw=1 et tw=79: -->