: # use perl -*- mode: Perl; -*- eval 'exec perl -S $0 "$@"' if $runnning_under_some_shell; # # ATTENTION Netescapers, Websurfers and other Internauts! # # Save this file as "pemberton.pl", when viewing or downloading it via WWW, # and make that file executable (under Unix: chmod 755 pemberton.pl). # $VERSION = "1996.12.24"; # minor change 2024-03-31: http to https $PROGRAM = "pemberton.pl"; # # File : pemberton.pl (first version: 1996.06.09) # Author: Eric Maryniak (e.maryniak@pobox.com) # When : 1996-12-24 16:09:21 (ISO 8601:1988 date/time of last mod) # And on: 2024-04-16 (minor change) when I: # replaced all home page pobox.com url's with home.xs4all.nl, because # Pobox.com dropped URL redirection on May 01, 2024 (2024-05-01). # Org. : Image Sciences Institute, department of Medicine at the University # of Utrecht ("Universiteit Utrecht)" in Dutch. # URL: http://www.cv.ruu.nl # WWW : https://maryniak.home.xs4all.nl/publications/pemberton.pl.txt # Discl.: There is no copyright on this program, you may use it freely # and/or modify it at will to suit your needs. # Mentioning my name, though, is appreciated! # Use of the program is entirely at your own risk. # I don't have the resources to "support" this program in any way; # it works for me and I thought I'd just share it with you, so you # can tailor it in whatever way you like. # I'd like to see "upgraded" and/or "generalized" versions of this # program if you've made such beasties. # Please don't be offended if I don't respond to e-mail; rest # assured your e-mail is always read and appreciated, but my # workload is currently such, that elm is running with a very # low priority ;-) # Furthermore, this program is not in any way endorsed or "approved" # by Steven Pemberton. My interpretation of his paper and the # application of his model to regular documents (instead of # journals) may be incorrect. E.g. the omission of the "double arrow", # to further simplify the model, may not be valid. In my opinion, # however, regular documents usually do not have same sections # across chapters. In a personal communication, Steven said he would # just leave the double arraw grayed out (i.e. not selectable). # As said, I just leave out the double arrow altogether. # What : Generates a set of documents according to Steven Pemberton's # three layer document model (although meant for online bulletins): # # o Publishing on the World Wide Web. # Conference book. Autumn 1995. # URL: http://www.nluug.nl/nluug/nj95/ # o SIGCHI Bulletin (online from januari 1996). # URL: http://www.acm.org/sigchi/bulletin/ # # Generated documents should strictly conform to HTML syntax and # (most) semantics as verified with weblint and sgmls: # # o Weblint package (Perl script) # URL: http://www.cre.canon.co.uk/~neilb/weblint/ # o Weblint interface via WWW # URL: http://www.unipress.com/cgi-bin/WWWeblint # o Another very nice weblint interface via WWW # URL: http://www.tiac.net/users/zach1/htmlcheck/htmlcheck.shtml # # o SGMLs interface via WWW # URL: http://www.webtechs.com/html-val-svc/ # o Another "Kinder" SGMLs interface via WWW # URL: http://ugweb.cs.ualberta.ca/~gerald/validate.cgi # # Exampl: If you have a base directory foo, then 3 chapter's with 2, 3 # and 4 sections, then this directory tree is generated: # # xxx/welcome.html (top level doc) # xxx/1/welcome.html (chapter 1) # xxx/1/1/welcome.html (section 1.1) # xxx/1/2/welcome.html (section 1.2) # xxx/2/welcome.html (chapter 2) # xxx/2/1/welcome.html (section 2.1) # xxx/2/2/welcome.html (section 2.2) # xxx/2/3/welcome.html (section 2.3) # xxx/3/welcome.html (chapter 3) # xxx/3/1/welcome.html (section 3.1) # xxx/3/2/welcome.html (section 3.2) # xxx/3/3/welcome.html (section 3.3) # xxx/3/4/welcome.html (section 3.4) # # Note that the default page is "welcome.html", you may want to # change this to "index.html" or something. The directory "foo" # is actually created at run-time and has the name of the # process id of this script (thus, a number xxx). # This is to avoid overwriting existing directories. # # True examples at the server http://www.rgd.nl (previous employer): # # http://www.rgd.nl/cccee/ # http://www.rgd.nl/webmaster/ # # Hmm...: This is a Perl script, tested with Perl version 5.001m under: # # o Linux 1.99.6 #1-pre-2.0 # o Sun Solaris 1.x (SunOS 4.x) and Solaris 2.x # # Thanks Larry! Power to the camels ;-) # # Why : I was not satisfied with existing HTML generators, where there # is an abundance of navigational concepts (up, down, next ...) # in the generated HTML. # The simplicity of Pemberton's model, at the basis of which # scientific research regarding human computer interfaces lies, # pleased me very much. # Instl : Save this file under the name "pemberton.pl" (when downloading # or saving it from WWW) # Bugs : This script is from the Q&D department. # A lot of things could have been done more elegant, but it works, # and "There's More Than One Way To Do It." (PP: 4). Yes, I know # there are such things as subroutines, but this grew as it grew! # Please excuse me for the copious amount of comments, I have just # started with Perl and use my source as a reference for new source! # Buglist/todoes: # 1. A proper manual, written as an HTML document set generated from # this script, is missing # 2. Bad input (control chars, letters when numbers should be given, # etc., is not handled well: you must do it right the first time! # This could be solved by using response files and giving the user # the opportunity, at program startup, to use a previously saved # response file (like the Gnu configure program does). # 3. ... at your own, and fix them as well :-] # Subroutines. # # Ahum, err... # Program start. # # This monolith should be Wirthified. # Here document (PP:72-73). # Don't put a space after "<<": put the delimiter directly after "<<" !! print < (max. 64 chars, HTML 2 recommendation!):\n"; chop ($title = ); print " is:\n[$title]\n\n"; print "Give short TITLE for navigation bars (possibly equal to <TITLE>):\n"; chop ($short_title = <STDIN>); print "short TITLE is:\n[$short_title]\n"; # Make a suggested name for the gif file, based on the short title, with # 1. all characters lowercased (common practice), use tr for this (PP:194): # "translate while copying a variable" # 2. all non-alfa and non-number characters deleted (also common practice) # "delete all non-alpha characters completely" ($gif_file = $short_title) =~ tr/A-Z/a-z/; $_ = $gif_file; # $gif_file must be copied to $_, because tr/A-Za-z0-9//cd; # a tr on $gif_file itself will not work $gif_file = $_.".gif"; # append ".gif" extension print "Suggested name for the logo gif filename, based on the short title:\n"; print "[$gif_file]\n\n"; print "Language of the document (for the language switch).\n"; print "Dutch (d) or English (e):\n"; ($lang = substr(<STDIN>,0,1)) =~ tr/A-Z/a-z/; # Read 1 char and lowercase it $lang = ($lang ne 'd' && $lang ne 'e') ? 'e' : $lang; # English if bad input $language{'d'} = 'Dutch'; $language{'e'} = 'English'; print "Language: [$language{$lang}]\n\n"; $base_lang{'d'} = "dutch"; $base_lang{'e'} = "english"; $x_rgd_organization{'d'} = "Image Sciences Institute"; $x_rgd_organization{'e'} = "Image Sciences Institute"; $x_rgd_legalnote{'d'} = "Lees: http://www.cv.ruu.nl/dutch/copyright.html"; $x_rgd_legalnote{'e'} = "Read: http://www.cv.ruu.nl/english/copyright.html"; $top_of_doc_note{'d'} = "Top van dit scherm document"; $top_of_doc_note{'e'} = "Top of this screen document"; $keyword_search{'d'} = "Zoeken in dit document"; $keyword_search{'e'} = "Keyword search in this document"; $navigation_prev{'d'} = "Vorige"; $navigation_prev{'e'} = "Previous"; $navigation_next{'d'} = "Volgende"; $navigation_next{'e'} = "Next"; $navprev = $navigation_prev{$lang}; $navnext = $navigation_next{$lang}; print "Language variables set:\n"; print "x_rgd_organization: [$x_rgd_organization{$lang}]\n"; print "x_rgd_legalnote : [$x_rgd_legalnote{$lang}]\n\n"; print "X-CV-CreatedBy, e.g. Eric Maryniak (e.maryniak\@pobox.com) :\n"; chop ($x_rgd_createdby = <STDIN>); print "X-CV-CreatedBy is:\n[$x_rgd_createdby]\n\n"; chop ($x_rgd_createdon = `date '+%Y-%m-%d'`); print "X-CV-CreatedOn is automatically set to ISO 8601:1988 form:\n". "[$x_rgd_createdon]\n\n"; print "Machine name (e.g. web, www.cv.ruu.nl) :\n"; chop ($machine_name = <STDIN>); print "Machine name is:\n[$machine_name]\n\n"; print "\nDo you want to specify a BASE for the HEAD section (N/y): "; ($ans = substr(<STDIN>,0,1)) =~ tr/A-Z/a-z/; # Read 1 char and lowercase it $ans = ($ans eq 'y') ? 'y' : 'n'; # No, if bad input if ($ans eq 'y') { print "Using a <BASE... in the <HEAD> section.\n"; $have_base_ref = 1; print "Specify _base_ of BASE HREF for document set, ALERT!\n"; print "1. Omit: http://$machine_name/\n"; print "2. Omit: trailing /\n"; print "Example: english/geology/mcg/publications/cccee\n"; chop ($base = <STDIN>); print "Base of BASE HREF is :\n[$base]\n"; print "URL's will start with:\n[http://$machine_name/$base]\n\n"; } else { print "NOT Using a <BASE... in the <HEAD> section.\n"; $have_base_ref = 0; } print "\nSpecify alternate base for document set (for the language switch):\n"; print "Example: dutch/geology/mcg/publications/cccee\n"; chop ($base_alt = <STDIN>); print "Alternate Base of BASE HREF, if any, is :\n[$base_alt]\n"; print "URL (no http://) in the language switch will be:\n[/$base_alt]\n\n"; print "Note: top home pages are (without the http://$machine_name part):\n"; print "[/$base/welcome.html]\n[/$base_alt/welcome.html]\n"; print "The tree for the alternate language is not generated.\n"; print "That must be done with a new run.\n\n"; print "Name of database for /cgi-bin/search?db=...:\n"; print "Example: mcg.publications.cccee\n"; chop ($db = <STDIN>); print "database is: [$db]\n\n"; print "Name of flag gif in bottom ruler (e.g. geo.gif):\n"; chop ($flag_gif = <STDIN>); print "flag gif is: [$flag_gif]\n\n"; print "Name of item in top level doc (e.g.: Chapter, Program, ...):\n"; chop ($chapter_name = <STDIN>); print "Name of top level item is: [$chapter_name]\n\n"; print "Name of item in level 1 doc (e.g.: Section, Project, ...):\n"; chop ($section_name = <STDIN>); print "Name of level 1 item is: [$section_name]\n\n"; ($subsection_name = $section_name) =~ tr/A-Z/a-z/; $subsection_name = "Sub".$subsection_name; ($subsubsection_name = $subsection_name) =~ tr/A-Z/a-z/; $subsubsection_name = "Sub".$subsubsection_name; print <<EO_User_1; Note: optionally, ${section_name}s may have: ${subsection_name}s and even ${subsubsection_name}s If present, the containing $section_name will have: o minitoc's to the ${subsection_name}s and ${subsubsection_name}s o local numbering to them o local back and forth hyperlinks to them but NOT a navigation tool a la the level 1 and 2 documents. EO_User_1 ## Chapters: numbers. print "Number of ${chapter_name}s in top level document:\n"; chop ($n_chapters = <STDIN>); print "Number of ${chapter_name}s: [$n_chapters]\n\n"; ## Chapters: names. print "Specify the names of the ${chapter_name}s.\n"; for ($i = 1; $i <= $n_chapters; $i++) { print " $chapter_name $i: "; chop ($chapter[$i] = <STDIN>); } ## Sections: numbers per chapter print "\nSpecify number of ${section_name}s for the ${chapter_name}s:\n"; for ($i = 1; $i <= $n_chapters; $i++) { print " $chapter_name $i: [$chapter[$i]]\n"; print " #${section_name}s: "; chop ($n_sections[$i] = <STDIN>); } ## Sections: names per chapter print "\nGive the names of the ${section_name}s of the ${chapter_name}s:\n"; for ($i = 1; $i <= $n_chapters; $i++) { print " $chapter_name $i: [$chapter[$i]]\n"; for ($j = 1; $j <= $n_sections[$i]; $j++) { print " $section_name $j: "; chop ($section{$i,$j} = <STDIN>); } } print "\nDo you want to specify:\n". "${subsection_name}s and possibly even ${subsubsection_name}s (N/y): "; ($ans = substr(<STDIN>,0,1)) =~ tr/A-Z/a-z/; # Read 1 char and lowercase it $ans = ($ans eq 'y') ? 'y' : 'n'; # No, if bad input if ($ans eq 'n') { for ($i = 1; $i <= $n_chapters; $i++) { for ($j = 1; $j <= $n_sections[$i]; $j++) { $n_subsections{$i,$j} = 0; } } } if ($ans eq 'y') { ## Subsections: numbers per section print "\nSpecify in the ${section_name}s numbers, possibly 0, of:\n". "${subsection_name}s and ${subsubsection_name}s\n"; for ($i = 1; $i <= $n_chapters; $i++) { print " $chapter_name $i: [$chapter[$i]]\n"; for ($j = 1; $j <= $n_sections[$i]; $j++) { print " $section_name $j: [$section{$i,$j}]\n"; print " #${subsection_name}s: "; chop ($n_subsections{$i,$j} = <STDIN>); if ($n_subsections{$i,$j} > 0) { for ($k = 1; $k <= $n_subsections{$i,$j}; $k++) { print " name of $subsection_name #$k ". "($i.$j-$k): "; chop ($subsection{$i,$j,$k} = <STDIN>); print " #${subsubsection_name}s: "; chop ($n_subsubsections{$i,$j,$k} = <STDIN>); if ($n_subsubsections{$i,$j,$k} > 0) { for ($l = 1; $l <= $n_subsubsections{$i,$j,$k}; $l++) { print " name of $subsubsection_name #$l ". "($i.$j-$k.$l): "; chop ($subsubsection{$i,$j,$k,$l} = <STDIN>); } } } } } } } $screen_line = 1; #print "\n${chapter_name}s and ${section_name}s entered:\n"; #for ($i = 1; $i <= $n_chapters; $i++) { # print " $chapter_name $i: [$chapter[$i]]\n"; # for ($j = 1; $j <= $n_sections[$i]; $j++) { # print " $section_name $j: $section{$i,$j}\n"; # } #} $wd = "$$"; print <<EOMSG1; OK!! About to generate HTML doc's and dir's in directory: $wd. Hit return: EOMSG1 $go = <STDIN>; $date = "ISO 8601:1988 date and time (TZ): ".`date '+%Y-%m-%d %H:%M:%S (%Z)'`; chop ($date); print "\nGenerating documents in directory '$wd' on\n$date\n...\n\n"; `mkdir $wd`; ## Top level document. $f = "$wd"."/welcome.html"; open OUT, ">$f" || die "Can't open $f for writing: $!\n"; print OUT <<EO_Level_1a1; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <!-- X-CV-Organization: $x_rgd_organization{$lang} --> <!-- X-CV-LegalNote : $x_rgd_legalnote{$lang} --> <!-- X-CV-Contents : $title --> <!-- X-CV-CommentsTo : webmaster\@cv.ruu.nl --> <!-- X-CV-CreatedBy : $x_rgd_createdby --> <!-- X-CV-CreatedOn : $x_rgd_createdon --> <!-- X-CV-LastModBy : $x_rgd_createdby --> <!-- X-CV-LastModOn : $x_rgd_createdon --> <!-- This HTML page was automatically generated by the Perl script --> <!-- $PROGRAM [vs. $VERSION], (c) Eric Maryniak, e.maryniak\@pobox.com --> <!-- on $date. --> <!-- URL: https://maryniak.home.xs4all.nl/publications/pemberton.pl.txt --> <!-- 2024-04-16: replaced all home page pobox.com url's with home.xs4all.nl, because Pobox.com dropped URL redirection on May 01, 2024 (2024-05-01) --> <HEAD> EO_Level_1a1 print OUT "<BASE HREF=\"http://$machine_name/$base/welcome.html\">\n" if $have_base_ref; print OUT <<EO_Level_1a2; <LINK REV=MADE HREF="mailto:webmaster\@cv.ruu.nl"> <TITLE>$title

$title


Bla 1: An indicative description of the document in 2 or 3 sentences.

Keywords: keyword1, keyword2, ..., of the whole document.


EO_Level_1a2 if ($n_chapters > 0) { print OUT "

${chapter_name}s

\n". "\n"; } print OUT <  $keyword_search{$lang}

Bla 2: A slightly more elaborate description with some interesting highlights!

Context
Bla 3: Higher level context(s), such as parent page of this page. EO_Level_1b if ($lang eq 'd') { # Dutch toolbar print OUT <


ICU/RUU, $date. EO_Level_1d close OUT; for ($c = 1; $c <= $n_chapters; $c++) { ## Level 1 doc's. $prev = $c - 1; $next = $c + 1; $d = "$wd/$c"; `mkdir $d`; $f = $d."/welcome.html"; open OUT, ">$f" || die "Can't open $f for writing: $!\n"; print OUT < EO_Level_2a1 print OUT "\n" if $have_base_ref; print OUT < $short_title - $c $chapter[$c] EO_Level_2a2 # Generate top navigation bar. Exactly the same as the bottom one. # Todo: change this to a subroutine. if ($c == 1) { # first chapter, no previous chapter print OUT "$chapter_name [\n"; } else { # non-first chapter, there is a previous chapter print OUT "$chapter_name [\n"; } print OUT " $short_title ,\n". " $c - $chapter[$c] ]\n"; if ($c == $n_chapters) { # last chapter, no next chapter print OUT "$chapter_name\n"; } else { # non-last chapter, there is a next chapter print OUT "$chapter_name\n"; } print OUT <

$chapter_name $c - $chapter[$c]

EO_Level_2b if ($n_sections[$c] > 0) { print OUT "

${section_name}s

\n". "
    \n"; } # Generate section toc. for ($i = 1; $i <= $n_sections[$c]; $i++) { print OUT "
  • $c.$i - ". "$section{$c,$i}\n"; } if ($n_sections[$c] > 0) { print OUT "
\n"; } print OUT <

 $keyword_search{$lang}


EO_Level_2c # Generate bottom navigation bar. Exactly the same as the top one. # Todo: change this to a subroutine. if ($c == 1) { # first chapter, no previous chapter print OUT "$chapter_name [\n"; } else { # non-first chapter, there is a previous chapter print OUT "$chapter_name [\n"; } print OUT " $short_title ,\n". " $c - $chapter[$c] ]\n"; if ($c == $n_chapters) { # last chapter, no next chapter print OUT "$chapter_name\n"; } else { # non-last chapter, there is a next chapter print OUT "$chapter_name\n"; } print OUT < EO_Level_2d close OUT; for ($s = 1; $s <= $n_sections[$c]; $s++) { ## Level 2 doc's. $prev = $s - 1; $next = $s + 1; $d = "$wd/$c/$s"; `mkdir $d`; $f = $d."/welcome.html"; open OUT, ">$f" || die "Can't open $f for writing: $!\n"; print OUT < EO_Level_3a1 print OUT "\n" if $have_base_ref; print OUT < $short_title - ${c}.${s} $section{$c,$s} EO_Level_3a2 # Generate top navigation bar. Exactly the same as the bottom one. # Todo: change this to a subroutine. if ($s == 1) { # first section, no previous section print OUT "$section_name [\n"; } else { # non-first section, there is a previous section print OUT "$section_name [\n"; } print OUT " $short_title ,\n". " $c - $chapter[$c] ]\n"; if ($s == $n_sections[$c]) { # last section, no next section print OUT "$section_name\n"; } else { # non-last section, there is a next section print OUT "$section_name\n"; } print OUT <

$section_name ${c}.${s} - $section{$c,$s}

EO_Level_3b1 if ($n_subsections{$c,$s} <= 0) { # No subsections. print OUT < Keywords: keyword1, keyword2, ..., of this $section_name.

Bla 1: actual text of this $section_name EO_Level_3b2 } else { # Subsections # Table of contents of sub(sub-)sections within section. print OUT <

    EO_Level_3b3 for ($i = 1; $i <= $n_subsections{$c,$s}; $i++) { print OUT <$i $subsection{$c,$s,$i} EO_Level_3b4 if ($n_subsubsections{$c,$s,$i} > 0) { # Subsubsections. print OUT " \n"; } } print OUT < $top_of_doc_note{$lang}. EO_Level_3b6 print OUT < Keywords: keyword1, keyword2, ..., of this $section_name. EO_Level_3b7 # Sub(sub-)sections within section with titles and empty content. for ($i = 1; $i <= $n_subsections{$c,$s}; $i++) { print OUT < $i $subsection{$c,$s,$i} EO_Level_3b8 if ($n_subsubsections{$c,$s,$i} <= 0) { print OUT <

    Bla 2-$i: actual text of this $subsection_name EO_Level_3b9 } for ($j = 1; $j <= $n_subsubsections{$c,$s,$i}; $j++) { print OUT < $i.$j $subsubsection{$c,$s,$i,$j}

    Bla 3-$i.$j: actual text of this $subsubsection_name EO_Level_3b10 } } } print OUT <  $keyword_search{$lang}


    EO_Level_3c # Generate bottom navigation bar. Exactly the same as the top one. # Todo: change this to a subroutine. if ($s == 1) { # first section, no previous section print OUT "$section_name [\n"; } else { # non-first section, there is a previous section print OUT "$section_name [\n"; } print OUT " $short_title ,\n". " $c - $chapter[$c] ]\n"; if ($s == $n_sections[$c]) { # last section, no next section print OUT "$section_name\n"; } else { # non-last section, there is a next section print OUT "$section_name\n"; } print OUT < EO_Level_3d close OUT; } # 1..n_sections[chapter] } # 1..n_chapters print "\nProgram ended succesfully.\n\n"; exit 0;