#!/bin/sh # html_cfg.sh 0.0.3, (c) 2008 by Patrick Boylan # not to be confused with cfg2html.pl . # # You can modify, redistribute, and pretty much do whatever you want # with this script under the terms of the GNU General Public License, # Version 2, or the new one if you prefer. If you didn't get a copy of # the GNU GPL with this program, look in /usr/share/common-licenses/ on # Debian-based systems, or http://gnu.org/licenses/gpl-2.0.txt . If # the URL should fail for some reason, they have a search engine. # # Again, this shouldn't be confused with Vlad Harchev's cfg2html.pl , # which produces much nicer HTML anyway. My goals are different. I # wanted a set of hyperlinked config files which are easily navigated # from within Lynx -- so, via the e)dit command, Lynx becomes its own # best configuration editor. You should be able to find the settings # you want to change, and change them more easily this way. # # With that in mind, I wanted the results to look as similar as # possible in a web browser or text editor. The plaintext view might # not be pretty, but I've tried to keep it legible. # CHANGES: # 0.0.3 * I *think* it's a POSIX-compliant /bin/sh script now. # * DOCTYPE declaration was omitted, because I wasn't sure # what DTD to put it under. WDG validator validates it # now [except for those Lynx-specific TAB elements]. # * Uses separate for loops to generate the HTML pages and # main index. Adds some unnecessary reptition, but it # should be easier to read. # * Fixed some of those multi-line echoes, so they won't # screw up the indentation [purely cosmetic; also for # legibility]. # # 0.0.2 * Tried doing more in memory, less with temp-files, but # that didn't seem to speed things up any. # * Rearranged the `case "$foo" in' thing so the most likely # possiblities are tested first. Went from a five minute # job to like, a minute on my old 233 mHz Compaq Armada. # * Went back to mostly temp-files. # * Commented the hell out of it. # # 0.0.1 * You mean, it actually did something this time? Whoah... nom="$(basename "$0")" tmp="lynx_cfg_tmp" sub="lynx_cfg.d" idx="lynx_cfg.html" phile="lynx_cfg" intro="html" hr="\n
" dtd=' ' how2 () { echo " Usage: $nom /path/to/lynx.cfg [/path/to/output_dir/] If no output directory is specified, the current directory is used. Either path may be relative or absolute, but the output directory must already exist. Also note that if you wish to use $idx as your lynx.cfg , the output directory *must* be its final destination. Moving your files around after running the script will invalidate all \`INCLUDE:' directives inside $idx , because these use absolute paths. If you only want a browsable HTML version of lynx.cfg to look at, this is not a problem; the HTML links are relative. But if this is what you're trying to do, I recommend using Vlad Harchev's excellent cfg2html.pl instead. " } if [ "$1" = "" ] || [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "--help" ] then how2 exit 0 fi if [ -f "$1" ] then lynx_cfg="$(cat "$1")" if [ "$lynx_cfg" = "" ] then echo "That Didn't Work." how2 exit 1 fi else echo "\`$1' is not a file." how2 exit 1 fi # Some half-hearted idiot-proofing. if [ "$2" = "" ] then src="$0" dest="`pwd`" elif [ -d "$2" ] then if [ "$(echo "$0" | grep '^\./')" != "" ] then src="`pwd`/$0" elif [ "$(echo "$0" | grep '^/')" != "" ] then src="$0" elif [ -x "`pwd`/$0" ] then src="`pwd`/$0" # Having `.' in your $PATH is a BAD idea, # but it could happen. fi cd "$2" dest="`pwd`" else echo "\`$2' is not a directory." how2 exit 1 fi # Still half-hearted. echo "Loaded \`$1', sorting lines..." # Declaring a few useful functions... scrubHeader () { # Strip the leading `.h1' and `.h2' from input. echo "$1" | cut --delimiter=' ' --fields='2-222' } scrubFileName () { # Convert the current line into a sensible filename # [eg, all lowercase, no spaces, no funky puctuation]. echo "$1" | tr '_' ' ' | tr --delete '[:punct:]' | \ tr -s ' ' '_' | tr '[:upper:]' '[:lower:]' } scrubLine () { # Use an HTML escape sequence if absolutely necessary. scrubbedLine="$1" while [ "$(echo "$scrubbedLine" | grep '<' -)" != "" ] do scrubbedLine="$(echo "$scrubbedLine" | sed 's/</\</')" # Any way to make sed do its own recursion? # This is a bit silly. done echo "$scrubbedLine" } num=0 tmp2="$tmp" while [ -e "$tmp2" ] do tmp2="${tmp}.$num" num=$(($num + 1)) # Just making sure the temp directory *does_not* # already exist, because it will be deleted later. done tmp="$tmp2" mkdir "$tmp" unset $num unset $tmp2 echo "Using \`$dest/$tmp' for temp-files..." if [ ! -d "$sub" ] then mkdir "$sub" fi IFS=' ' for line in $lynx_cfg do case "$line" in \#*\<*) datOut="$datOut$(scrubLine "$line")\n" ;; \#*) datOut="$datOut$line\n" ;; .*) case "$line" in .h2\ *) line="$(scrubHeader "$line")" if [ "$datOut" != "" ] then if [ "$intro" = "intro" ] then echo "<PRE>\n$datOut</PRE>" \ >> "$tmp/${phile}.$intro" else echo "<PRE>\n$datOut\n</PRE>$hr" \ >> "$tmp/${phile}.$intro" fi datOut='' # # Flush the output buffer before changing # the subject. fi intro="main" aname="$(scrubFileName "$line")" echo "<H2><A HREF=\"../$idx#$phile\" NAME=\"$aname\"\n\n\n >$line</A></H2>" \ >> "$tmp/${phile}.$intro" # H2 header for this section. echo " <LI><A HREF=\"$sub/${phile}.html#$aname\">$line</A></LI>" \ >> "$tmp/${phile}.lst" # Sub-headings list for the main index. echo " <LI><A HREF=\"#$aname\">$line</A></LI>" \ >> "$tmp/${phile}.ls2" # Sub-headings list for each file [ToC]. ;; .h1\ *) line="$(scrubHeader "$line")" lsH1="$lsH1$line\n" # # Store .h1 headers for future reference. if [ "$datOut" != "" ] then if [ "$intro" = "intro" ] then echo "<PRE>\n$datOut</PRE>" \ >> "$tmp/${phile}.$intro" else echo "<PRE>\n$datOut\n</PRE>$hr" \ >> "$tmp/${phile}.$intro" fi datOut='' # # Flush the output buffer before changing # the subject. fi intro="intro" # # Any text which occurs after the .h1 line, but # before any .h2 lines, will be an introduction # to this section. phile="$(scrubFileName "$line")" # # Further output under this .h1 header will go into # `${phile}.html'. ;; .ex) datOut="$datOut#\n# Example:\n" ;; .ex\ *) datOut="$datOut#\n# Examples:\n" ;; *) datOut="$datOut#\n" # Missed .nf and .fi, but with no formatting # to begin with, there's no need to turn it # off. # No need to turn it back on again, either. ;; esac ;; *\<*) datOut="$datOut<!>$(scrubLine "$line") <!--\n" datOut="$datOut# The line above is escaped for HTML viewers.\n" datOut="$datOut# Active configuration item follows:\n" datOut="$datOut$line\n" datOut="$datOut# -->\n" ;; *) datOut="$datOut$line\n" ;; esac done unset $lynx_cfg if [ "$datOut" != "" ] then echo "<PRE>\n$datOut\n</PRE>$hr" \ >> "$tmp/${phile}.$intro" unset $datOut # # Don't forget to flush. fi # Okay, so... Now that we've dissected lynx.cfg , # let's try to put it back together again. # # Won't this be fun... echo "Split \`$1' into temp-files. Re-assembling..." lsH1="$(echo "$lsH1" | sort -u)" for line in $lsH1 do phile="$(scrubFileName "$line")" { echo "$dtd$line" echo "" echo "

$line

" } > "$sub/${phile}.html" # # Start a new file, based on .h1 directives in lynx.cfg . if [ -f "$tmp/${phile}.intro" ] then cat "$tmp/${phile}.intro" \ >> "$sub/${phile}.html" fi if [ -f "$tmp/${phile}.ls2" ] then { echo echo "

Sub-headings within this document:

" echo "$hr" } >> "$sub/${phile}.html" fi # Those .h2 headings go here. if [ -f "$tmp/${phile}.main" ] then cat "$tmp/${phile}.main" \ >> "$sub/${phile}.html" fi # Dump the main text into your new file [after ToC]. done echo "Generating index, \`$idx'..." echo "${dtd}lynx.cfg file.

lynx.cfg file.

" > "$idx" cat "$tmp/$idx" >> "$idx" # # Opening lines and intro for lynx_cfg.html . echo "\n

Index by category:

\n" > "$tmp/$idx" # # Note that we're still using the temp-file for the detailed # index [no ToC in main file yet, and that should go first]. # Also clears the temp-file, because whatever was in it has # already been catted into the final copy. inc='' toc='' for line in $lsH1 do phile="$(scrubFileName "$line")" echo "

$line

" \ >> "$tmp/$idx" # # Add a new header for this section of lynx_cfg.html # [the temp-file, not the real one yet]. if [ -f "$tmp/${phile}.intro" ] then cat "$tmp/${phile}.intro" \ >> "$tmp/$idx" fi # Re-use the introduction for this section. if [ -f "$tmp/${phile}.lst" ] then { echo "$hr" } >> "$tmp/$idx" fi # Those .h2 sub-headings go here, too. inc="${inc}INCLUDE:$dest/$sub/${phile}.html\n" # # Add this file to the list of INCLUDE directives. toc="${toc} $line $line\n" # # Add this header to the table of contents [literally a table, # in this case]. done echo "" \ >> "$idx" unset $inc # # Dump your INCLUDE directives into lynx_cfg.html [final, not temp]. echo "

Primary configuration headings:     

$toc
In this document: In its own file:
$hr" \ >> "$idx" unset $toc # # Now the table of contents. cat "$tmp/$idx" >> "$idx" # And the detailed index [stored in the temp-file]. echo "Removing temp-files, $dest/$tmp ..." rm -rf "$dest/$tmp" echo "Add closing to finish files..." prevF='' thisF='' for nextT in $lsH1 do nextF="$(scrubFileName "$nextT").html" if [ "$thisF" = "" ] then { echo echo "

" echo " First Item: $nextT" echo "

" echo " HTML generated on" echo "
$(date)" echo "
by $nom -" echo " For Free.
" echo "

" echo "" } >> "$idx" elif [ "$prevF" = "" ] then { echo echo "

" echo " Next: $nextT" echo "

" echo "" } >> "$sub/$thisF" else { echo echo "

" echo " Prev: $prevT" echo " || Next: $nextT" echo "

" echo "" } >> "$sub/$thisF" fi prevF="$thisF" thisF="$nextF" prevT="$thisT" thisT="$nextT" done echo "

Prev: $prevT

" >> "$sub/$thisF" echo "Writing document info..." echo "${dtd}About $nom

$nom

$(head -n 45 "$src" | tail -n '+2' | tr '#' ' ')
$hr

Source || License || Back to $idx

$hr
$(tail -n 5 "$src" | tr '#' ' ')
" > "$sub/${nom}-about.html" cat "$src" > "$sub/${nom}-script.txt" # Include the script in its own documentation. echo "Done." # Dedicated to the memory of Cheetah the cat, and her invaluable # help with the Bash scripting language. [Okay, 31337 H4x0R k!tty # computing tip here: What she would actually do was fall asleep on # my lap, thereby encouraging me to sit still for extended periods # of time. It helped, and I'm grateful. I really miss her.]