::namespace eval ::qw::html {} ::proc ::qw::html::encode {Text} { /* { Eliminates tcl special characters so that they will not interfere with future invocations of the ::subst command. We typically used this proc when putting raw data from a NewViews field into html. Fot example, a description field could contain any combination of special characters that interfere with tcl evaluation. Note that ampersand must be substituted first because it is put in the output stream. In addition, it does have to eliminated because it is itself a special html character. */ } ::regsub -all {\&} $Text {\&} Text; ::regsub -all {\[} $Text {\[} Text; ::regsub -all {\]} $Text {\]} Text; ::regsub -all {\$} $Text {\$} Text; ::regsub -all {\"} $Text {\"} Text; ::regsub -all {\\} $Text {\\} Text; ::regsub -all {\<} $Text {\<} Text; ::regsub -all {\>} $Text {\>} Text; ::regsub -all {\{} $Text {\{} Text; ::regsub -all {\}} $Text {\}} Text; ::return $Text; } ::proc ::qw::html::encode_light {Text} { /* { Eliminates tcl special characters so that they will not interfere with future invocations of the ::subst command. We typically used this proc when putting raw data from a NewViews field into html. Fot example, a description field could contain any combination of special characters that interfere with tcl evaluation. Note that ampersand must be substituted first because it is put in the output stream. In addition, it does have to eliminated because it is itself a special html character. */ } ::regsub -all {\$} $Text {\$} Text; ::regsub -all {\[} $Text {\[} Text; ::regsub -all {\]} $Text {\]} Text; /* { ::regsub -all {\&} $Text {\&} Text; ::regsub -all {\"} $Text {\"} Text; ::regsub -all {\\} $Text {\\} Text; ::regsub -all {\<} $Text {\<} Text; ::regsub -all {\>} $Text {\>} Text; ::regsub -all {\{} $Text {\{} Text; ::regsub -all {\}} $Text {\}} Text; */ } ::return $Text; } # -------------------------------------------------------- # ::qw::html::formatter class # -------------------------------------------------------- /* { 2.28.3 How can we add attributes. [p {href="/a/b/c" class="hello"} { }] [p [::sargs .href "/a/b/c" .class "hello"] { }] [p { } .href "/a/b/c" .class "hello"]; Produces html using render method. The render method takes an argument and performs a ::subst on it within the context of a local method. This means that the "script" has access to all of the methods of this html format class. The put method appends to a buffer which is ultimately returned by the render method. That way the script can build up the buffer on the fly and does not have to worry about accumulating the resulting formatted text. We keep things here ultra simple. If you want access to raw html you can just put it in your script. The important points are that by using ::subst you have access to every tcl has to off, and because it is evaluated within the context of a local method, you also have access to the formatter, simple though it may be. Images ------ When the target is chtml we maintain _images, an array of images. Each element name is the original path to the image file and the value is a unique number followed by the original extension. We keep the extension because the eventual browser, i.e. hh.exe, may depend on these extensions. The reason for doing this is that we will eventually end up copying all images to the chtml project directory so that they can be accessed using relative paths. hh.exe cannot easily access file paths outside its own scope. .target chtml Need special processing for links, images, indexes, etc. "" The default. Take no special action. Links/Bookmarks --------------- For now links are to other pages within the same help hierarchy and thus end up within the chm. Each page, link, and bookmark has a unique id. A link can link to a page or a bookmark. _bookmarks_references Array indexed by bookmark id. Content is the page id containing the bookmark. _bookmarks_pages Array indexed by bookmark id. Content is a list of page ids of the pages that reference the bookmark. _links is a list of all links where each element is a structure: .page_id The page containing the link. .id The page id that the link refers to. .bookmark The books mark, if any, that the page refers to. */ } ::itcl::class ::qw::html::formatter { /* { _root_directory is needed to complete the path to image files. Paths within a help page are relative to the root of the page. _root_directory completes the path to the root of disk containing the root page. */ } protected variable _target; protected variable _root_directory; protected variable _compiler; protected variable _images; # indexed by source path, content is path in chm protected variable _unique_id 0; # protected variable _current_page_id ""; # protected variable _current_page_path ""; protected variable _sargs ""; method constructor {sargs} { ::array set _images ""; ::set _target [::sargs::get $sargs .target]; ::set _root_directory [::sargs::get $sargs .root_directory]; ::set _compiler [::sargs::get $sargs .compiler]; return ""; } destructor { } method render {s_args} { /* { This is old code I left in case some other obscure code uses it. But it is deprecated. */ } ::qw::try { if {[::sargs::get $s_args .path] ne ""} { ::sargs::var::+= s_args [::qw::file::info [::sargs::get $s_args .path]]; } ::return [::subst -nobackslashes [::sargs::get $s_args .body]]; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Could not render a page into html."]; } } method body_render {sargs} { /* { Usage: ::set FormattedPage [$Formatter body_render .body $Body]; We are given a page and we return a page. */ } /* { Happened when I had an error message with the tree, i.e. not flat error window displayed, and hit help button. */ } /* { yes we were called when database_download was run. Don't know why. Might be worth checking out. */ } ::set _sargs $sargs; ::qw::try { if {[::sargs::get $sargs .path] ne ""} { ::sargs::var::+= sargs [::qw::file::info [::sargs::get $sargs .path]]; } ::if {0} { ::set RenderedBody [::subst -nobackslashes [::substify::substify [::sargs::get $sargs .body] <% %>]]; } ::if {1} { ::set RenderedBody [::subst -nobackslashes [::sargs::get $sargs .body]]; } ::set RenderedPage $sargs; ::sargs::var::set RenderedPage .body $RenderedBody; ::return $RenderedPage; } catch Exception { ::qw::throw [::qw::exception::nest .sub $Exception .super "Could not render a body into html."]; } } method page_render {sargs} { /* { sargs is a structure that contains everything about the page including the page body. In addition, it has all arguments originally passed to the chtml script. The sargs variable is available to the page being processed and we use it mainly to extract .odb.object when appropriate such as in about.qw_help. We are given a page and we return the rendered (html) version of the page. */ } ::set rwb1_debug 0; ::qw::try { ::set _sargs $sargs; # ::if {$rwb1_debug} {::puts "rwb1_debug,page_render,sargs==\n[::sargs::format [::sargs::unset $sargs .body]]";} ::if {$rwb1_debug} {::puts "rwb1_debug,page_render,1000.0,page_id==[::sargs::get $sargs .id]";} ::if {$rwb1_debug} {::puts "rwb1_debug,page_render,1000.0,page_file_path==[::sargs::get $sargs .page_file_path]";} ::if {$rwb1_debug} {::puts "rwb1_debug,page_render,1000.0,path==[::sargs::get $sargs .path]";} if {[::sargs::get $sargs .path] ne ""} { ::sargs::var::+= sargs [::qw::file::info [::sargs::get $sargs .path]]; } ::set RenderedTitle [::subst -nobackslashes [::sargs::get $sargs .title]]; ::if {1} { ::set RenderedBody [::subst -nobackslashes [::sargs::get $sargs .body]]; } ::set RenderedPage $sargs; ::sargs::var::set RenderedPage .title $RenderedTitle; ::sargs::var::set RenderedPage .body $RenderedBody; ::sargs::var::set RenderedPage .body [::sargs::get [page_wrap $RenderedPage] .body]; ::return $RenderedPage; } catch Exception { ::qw::throw [::qw::exception::nest .sub $Exception .super "Could not render a page into html."]; } } /* { # method body_render_2.30.3 {sargs} { /* { Usage: ::set FormattedPage [$Formatter body_render .body $Body]; We are given a page and we return a page. */ } ::qw::try { if {[::sargs::get $sargs .path] ne ""} { ::sargs::var::+= sargs [::qw::file::info [::sargs::get $sargs .path]]; } ::set RenderedBody [::subst -nobackslashes [::sargs::get $sargs .body]]; ::set RenderedPage $sargs; ::sargs::var::set RenderedPage .body $RenderedBody; ::return $RenderedPage; } catch Exception { ::qw::throw [::qw::exception::nest .sub $Exception .super "Could not render a body into html."]; } } method page_render2.30.3 {s_args} { /* { s_args is a structure that contains everything about the page including the page body. In addition, it has all arguments originally passed to the chtml script. The s_args variable is available to the page being processed and we use it mainly to extract .odb.object when appropriate such as in about.qw_help. We are given a page and we return a page. */ } ::qw::try { if {[::sargs::get $s_args .path] ne ""} { ::sargs::var::+= s_args [::qw::file::info [::sargs::get $s_args .path]]; } ::set RenderedTitle [::subst -nobackslashes [::sargs::get $s_args .title]]; ::set RenderedBody [::subst -nobackslashes [::sargs::get $s_args .body]]; ::set RenderedPage $s_args; ::sargs::var::set RenderedPage .title $RenderedTitle; ::sargs::var::set RenderedPage .body $RenderedBody; ::sargs::var::set RenderedPage .body [::sargs::get [page_wrap $RenderedPage] .body]; ::return $RenderedPage; } catch Exception { ::qw::throw [::qw::exception::nest .sub $Exception .super "Could not render a page into html."]; } } */ } /* { method clear {} { ::set _buffer ""; return $this; } method put {Src} { ::append _buffer $Src; return $this; } */ } method list_to_string {List} { /* { undo Tcl's quoting due to list protection This leaves a space at the beginning if the string is non-null but this is always desirable in the HTML context in which it is called and the resulting HTML looks more readable. (It makes the Tcl callers a little less readable - however, there aren't more than a handful and they're all right here, so we'll live with it.) */ } ::set String ""; ::foreach Item $List {::append String " $Item";} # remove first space if possible # regexp "^ ?(.*)" $String Dummy String return $String } # -------------------------------------------------------- # header methods # -------------------------------------------------------- method h1 {Arg} {::return [h 1 $Arg];} method h2 {Arg} {::return [h 2 $Arg];} method h3 {Arg} {::return [h 3 $Arg];} method h4 {Arg} {::return [h 4 $Arg];} method h5 {Arg} {::return [h 5 $Arg];} method h6 {Arg} {::return [h 6 $Arg];} method h {Number Arg} { ::return "$Arg\n"; } /* { method h1 {args} {::return [::eval h 1 $args];} method h2 {args} {::return [::eval h 2 $args];} method h3 {args} {::return [::eval h 3 $args];} method h4 {args} {::return [::eval h 4 $args];} method h5 {args} {::return [::eval h 5 $args];} method h6 {args} {::return [::eval h 6 $args];} method h {Number args} { ::return "$args"; } */ } /* { method h {Number args} { ::puts "header h$Number $args" ::set Result "1} { ::append Result [::subst "[lrange $args 0 [::expr [::llength $args]-2]]";] set args [::lrange $args end end] } ::set args [list_to_string $args]; ::append Result ">[::lindex $args 0]"; ::puts "header result \"$Result\"" return $Result; } */ } # -------------------------------------------------------- # special character methods # -------------------------------------------------------- method lt {} {::return "<";} method gt {} {::return ">";} method amp {} {::return "&";} method quote {} {::return """;} method left_bracket {} {::return "[";} method right_bracket {} {::return "]";} method enspace {} {::return " ";} method emspace {} {::return " ";} method dollar {} {::return "$";} method dollar_sign {} {::return "$";} method backslash {} {::return "\";} method nbspace {} {::return " ";} ;# nonbreaking space method tm {} {::return "®";} ;# registered trademark # method copyright {} {::return "©";} method copyright {} {::return "©";} method isochar {n} {::return "&#$n;";} method breakable {} {::return "";} method unbreakable_string {s} {::return "$s";} method unbreakable {cmd} { cgi_puts "" _cgi_close_proc_push "cgi_puts " uplevel 1 $cmd _cgi_close_proc } method nl {args} { ::set Buf "" } # -------------------------------------------------------- # font methods # -------------------------------------------------------- method bold {Src} {::return "[::subst $Src]";} method b {Src} {::return "$Src";} # method bold {args} {::return "$args";} method italic {Src} {::return "$Src";} method underline {Src} {::return "[::subst $Src]";} method strikeout {Src} {::return "$Src";} method subscript {Src} {::return "$Src";} method superscript {Src} {::return "$Src";} # method typewriter {Src} {::return "[::subst $Src]";} method typewriter {Src} { ::set Result "[::subst $Src]"; ::return $Result; } method blink {Src} {::return "$Src";} method emphasis {Src} {::return "$Src";} method strong {Src} {::return "$Src";} method cite {Src} {::return "$Src";} method sample {Src} {::return "$Src";} method keyboard {Src} {::return "$Src";} method kbd {Src} {::return "$Src";} method variable {Src} {::return "$Src";} method definition {Src} {::return "$Src";} method big {Src} {::return "$Src";} method small {Src} {::return "$Src";} method tt {Src} { ::qw::warning 314120150223130152 "[::qw::methodname] - tt tag not implemented in html5 - use kbd tag."; ::return "$Src"; } method kdb {Src} { ::return "$Src"; } method pre {Src} {::return "
$Src
";} method tcl_code {Src} {::return "
$Src
";} method basefont {Size} {::return "";} method font {args} { ::set Buf "[::lindex $args end]" } # method basefont {Size} {::return [$_formatter h1 $args];} # ------------------------------------------------------------ # horizontal ruler method # ------------------------------------------------------------ # ------------------------------------------------------------ # horizontal ruler method # ------------------------------------------------------------ method hr {args} { ::set Result ""; ::return $Result; } # -------------------------------------------------------- # paragraph methods # -------------------------------------------------------- method br {args} { ::set Result ""; ::return $Result; } method paragraph {Src} { ::return [::subst -nobackslashes "

$Src

\n"]; } method images {} { ::return [::array get _images]; } method img {sargs} { /* { attributes dynsrc Explorer only for some kind of dynamic loading of movies. lowsrc Netscape only for preloading at lower resolution. alt Alternative text the browser can display. Browsers may also display this when mouse is over graphic. Up to 1024 characters. longdesc url of objject containing a long description. align left,right,top,middle,bottom .width .height Kludge Alert: The formatter must know if the target is chtml so that img file paths can be manipulated accordingly. 2.11.4 Added the .base64 argument. If this argument exists then the image is the value of the argument in base64 and must be put to a temporary file for actual use. */ } ::set rwb1_debug 0; ::if {$rwb1_debug} {::puts "rwb1_debug,img,1000.0,sargs==$sargs";} ::if {$rwb1_debug} {::puts "rwb1_debug,img,1000.1,src==[::sargs::get $sargs .src]";} ::if {$rwb1_debug} {::puts "rwb1_debug,img,1000.2,page_file_path==[::sargs::get $_sargs .page_file_path]";} ::qw::try { ::if {[::sargs::exists $sargs .base64]} { ::set FileName [::sargs::get $sargs .base64.filename]; ::set CipherText [::sargs::get $sargs .base64.data]; ::set PlainText [::base64::decode $CipherText]; ::set File [::file join [::qw::fileutil::temporary_directory] $FileName]; ::set Handle [::open $File w+]; ::fconfigure $Handle -translation binary; ::puts -nonewline $Handle $PlainText; ::close $Handle; ::sargs::var::set sargs .src $File; ::sargs::var::unset sargs .base64; } ::set Result ""; ::if {$rwb1_debug} {::puts "rwb1_debug,img,1000.99,result==$Result";} ::return $Result; } catch Exception { ::qw::throw [::qw::exception::nest .super $Exception .sub "Encountered error in img method with sargs \"$sargs\"."]; } } /* { method p {args} { ::set Result " 1} { ::append Result "[lrange $args 0 [::expr [::llength $args]-2]]" ::set args [::lrange $args end end] } ::set args [::subst $args]; ::set args [list_to_string $args]; ::append Result ">[::lindex $args 0]

\n" return $Result; } */ } # method p1 {Src} {::return [put [paragraph [::subst $Src]]];} # method p {Src} {::return [paragraph [::subst $Src]];} method p {Src} { ::return [::subst -nobackslashes "

$Src

\n"]; } # method p {Src} {::return [paragraph [::subst [::string trim $Src]]];} method code {Src} { ::return [::subst "$Src\n"]; } method div {args} { /* { Usage: tagged_block .block_tag_list block_tag_nv2 {...body...} Note that the body is a single argument but the preceding arguments form a sargs structure. We do this for compatibility with other commands. The args, mainly the .block_tag_list is passed to a callback in the compiler. We did it this way so could piggy back on the compiler and not have to pass additional argumants (say the callback) to the formatter. */ } ::set rwb1_debug 0; ::if {$rwb1_debug} {::puts "rwb1_debug,div,1000.0,args==\n$args";} ::if {$rwb1_debug} {::puts "rwb1_debug,div,1000.0,_sargs==\n$_sargs";} ::set Body [::lindex $args end]; ::set args [::lrange $args 0 end-1]; ::if {[::llength $args]!=0} { ::if {[::sargs::is_primitive $args]} { ::qw::throw "div - invalid structured arguments \"$args\""; } ::if {$rwb1_debug} {::puts "rwb1_debug,div,1000.1";} ::sargs::marshal; ::if {$rwb1_debug} {::puts "rwb1_debug,div,1000.2";} /* { Perform the callback through the compiler. Note that we append the body which is probably overkill and we do it with a field name to make sure it is a properly formatter structure. */ } ::set IsHit [$_compiler chtml_block_tags_hit $sargs .body $Body]; ::if {!$IsHit} { ::if {$rwb1_debug} {::puts "rwb1_debug,div,1000.4";} ::return ""; } ::if {$rwb1_debug} {::puts "rwb1_debug,div,1000.5";} } ::return [::subst -nobackslashes "
$Body
"]; } method span {args} { /* { See all div comments. */ } ::set rwb1_debug 0; ::if {$rwb1_debug} {::puts "rwb1_debug,span,1000.0,args==\n$args";} ::if {$rwb1_debug} {::puts "rwb1_debug,span,1000.0,_sargs==\n$_sargs";} ::set Body [::lindex $args end]; ::set args [::lrange $args 0 end-1]; ::if {[::llength $args]!=0} { ::if {[::sargs::is_primitive $args]} { ::qw::throw "span - invalid structured arguments \"$args\""; } ::if {$rwb1_debug} {::puts "rwb1_debug,span,1000.1";} ::sargs::marshal; ::if {$rwb1_debug} {::puts "rwb1_debug,span,1000.2";} /* { Perform the callback through the compiler. Note that we append the body which is probably overkill and we do it with a field name to make sure it is a properly formatter structure. */ } ::set IsHit [$_compiler chtml_block_tags_hit $sargs .body $Body]; ::if {!$IsHit} { ::if {$rwb1_debug} {::puts "rwb1_debug,span,1000.4";} ::return ""; } ::if {$rwb1_debug} {::puts "rwb1_debug,span,1000.5";} } ::return [::subst -nobackslashes "$Body"]; } method qw_commandline {Src} { ::return [bold [typewriter $Src]]; } method qw_code_inline {Src} { ::return [typewriter $Src]; } method qw_code {Src} { ::set Src [::string trim $Src]; ::set Src [::string map {\r ""} $Src]; ::set Src [::string map {\\n "\\n"} $Src]; ::set Src [::string map {\n "
"} $Src]; ::set Src [::string map {"\\\\" "\\
"} $Src]; ::set Src [::string map {"\t" " "} $Src]; # ::return [::subst "
$Src
\n"]; ::return "
$Src
\n"; } method qw_code1 {Src} { ::set SrcLineList [::split $Src "\n"]; ::set DstLineList ::foreach SrcLine $LineList { ::set DstLine ""; ::set i 0; ::while {$i<[::string length $SrcLine]} { ::set Char [::string index $SrcLine $i]; ::incr i; ::if {$Char eq "\t"} { ::append DstLine " "; ::continue; } ::append DstLine [::string range $SrcLine $i end]; ::break; } } ::return $DstLine; ::set Src [::string trim $Src]; ::set Src [::string map {\r ""} $Src]; ::set Src [::string map {\n "
"} $Src]; # ::return [::subst "
$Src
\n"]; ::return "
$Src
\n"; } method qw_code_numbered {Src} { /* { Like code method but numbers the lines, starting at 1. Leading tabs are first replaced with 4 chars each. Then we overwrite the number of spaces necessary for the number. */ } ::set Src [::string trimright $Src]; ::set Src [::string map [::list "\r" ""] $Src]; ::set Src1 [::string map [::list "\\\n" "\\n"] $Src]; ::set LineList [::split $Src1 "\n"]; ::set Result ""; # ::set LineList [::split $Src "\n"]; ::set LineNumber 1; ::foreach SrcLine $LineList { ::if {$LineNumber==1&&[::string trim $SrcLine] eq ""} { ::continue; } ::set SrcLine [::string trimright $SrcLine]; # Get rid of possible cr's. ::if {[::string index $SrcLine end] eq "\\"} { /* { Lots of source code contains line continuations and replacing them with \ seems to be the best way to deal with them. */ } ::set SrcLine [::lreplace $SrcLine end end "\"]; } ::set Prefix " "; ::set Length [::string length $SrcLine]; ::for {::set i 0} {$i<$Length} {::incr i} { ::set Char [::string index $SrcLine $i]; ::switch -- $Char { "\t" { ::append Prefix " "; } " " { ::append Prefix " "; ::continue; } default { ::break; } } } ::set DstLine [::string range $SrcLine $i end]; ::set LineNumberLength [::string length $LineNumber]; ::set Prefix [::string replace $Prefix 0 [::expr {$LineNumberLength-1}] $LineNumber]; # ::set Prefix "$LineNumber[::string range $Prefix $LineNumberLength end]"; ::append Result "${Prefix}${DstLine}
"; ::incr LineNumber; } ::return "
$Result
\n"; ::return $Result; } method paragraphs {Src} { ::set Result ""; foreach Arg $Src { ::append Result [paragraph $Arg]; } return $Result; } # -------------------------------------------------------- # list methods # -------------------------------------------------------- method bullets {args} {::return [::eval bullets1 $args];} method numbered {args} {::return [::eval numbered1 $args];} method definitions {args} {::return [::eval definitions1 $args];} /* { method bullets {args} {::return [::eval bullets1 [::subst $args]];} method numbered {args} {::return [::eval numbered1 [::subst $args]];} method definitions {args} {::return [::eval definitions1 [::subst $args]];} */ } /* { method listOrdered {args} {::return [$_formatter listOrdered $args];} method listUnordered {args} {::return [$_formatter listUnordered $args];} */ } /* { method ol {args} { ::set Result "\n"; ::append Result "\n"; ::return $Result; } */ } method ul {args} { ::if {$::qw::verbose(help)} {::puts "ul args $args";} ::set Result "\n"; ::append Result [list_to_string [::subst $args]]; ::append Result "\n"; ::if {$::qw::verbose(help)} {::puts "ul returning $Result";} ::return $Result; } method ol {args} { ::if {$::qw::verbose(help)} {::puts "ol args $args";} ::set Result "\n"; ::append Result [list_to_string [::subst $args]]; ::append Result "\n"; ::if {$::qw::verbose(help)} {::puts "ol returning $Result";} ::return $Result; } method li {args} { ::if {$::qw::verbose(help)} {::puts "li args $args";} ::set Result "\n"; ::if {[::sargs::is_primitive $args]} { ::set Contents [list_to_string [::subst $args]]; } else { ::set Contents [::sargs::get $args .contents]; } ::append Result $Contents; ::append Result "\n"; ::if {$::qw::verbose(help)} {::puts "li returning $Result";} ::return $Result; } method dl {args} { ::if {$::qw::verbose(help)} {::puts "dl args $args";} ::set Result "\n"; ::append Result [list_to_string [::subst $args]]; ::append Result "\n"; ::if {$::qw::verbose(help)} {::puts "dl returning $Result";} ::return $Result; } method dt {args} { ::if {$::qw::verbose(help)} {::puts "dt args $args";} ::set Result "\n"; ::if {[::sargs::is_primitive $args]} { ::set Contents [list_to_string [::subst $args]]; } else { ::set Contents [::sargs::get $args .contents]; } ::append Result $Contents; ::append Result "\n"; ::if {$::qw::verbose(help)} {::puts "dt returning $Result";} ::return $Result; } method dd {args} { ::if {$::qw::verbose(help)} {::puts "dt args $args";} ::set Result "\n"; ::if {[::sargs::is_primitive $args]} { ::set Contents [list_to_string [::subst $args]]; } else { ::set Contents [::sargs::get $args .contents]; } ::append Result $Contents; ::append Result "\n"; ::if {$::qw::verbose(help)} {::puts "dd returning $Result";} ::return $Result; } method link {args} { #ms-its:c:/rwb20_help_chm/nv2.chm::/314120040421124256.htm#314120040828145116 /* {

This should link to a page in the old help chm.

*/ } /* { Example in manual.qw_help to link to another page within manual. See the [link .id 150220040811161430 {[bold "Executive Summary"]}] for a brief overview. Example in error help to link to page in manual.chm (link is wrapped in list item). [li {[link .chm $::qw_manual_file .id 314120050422104251 {More on Versions and Updating}]}] The major difference is that the error help is dynamic and can find the chm file. Link Problem: Suppose a workshop chm includes a page from the manual that links to a another page that is in the manual but not the workshop. What we do is check whether the target page is a hit on the tags, and if it isn't then we do not attempt the link. If we could figure out the target chm file we could attempt the link but we still will not know what directory it will be in on a user machine. If we happen to know that the target page is also included in the workshop then we could link to that page in the workshop. This might actually work, but to do so we will have to manage the includes. The link to a page looks like: ...body... The link to bookmark 314120091231235959 within a page looks like: ...body... */ } ::qw::try { ::set s_args [::lrange $args 0 end-1]; ::set Body [::lindex $args end]; ::set TargetPageId [::sargs::get $s_args .id]; ::if {$TargetPageId eq ""} { ::qw::throw \ .text "qw::html::link - no .id argument." \ .error_id 314120170213110440 \ ; } ::set ThisPageId [qw_s_args .id]; ::set Compiler [qw_s_args .chtml.compiler]; ::if {$Compiler ne "" && ![::sargs::exists $s_args .chm]} { /* { We check to ensure the target page exists. However, if .chm is specified then the page is in another file and we cannot check. For example, we are linking from an error message into the manual. */ } ::set Page [$Compiler chtml_page_from_id $s_args]; ::if {$Page eq ""} { /* { The target page does not exist. */ } ::qw::throw "Help page \"$ThisPageId\" attempted to link to non-existing page \"$TargetPageId\"."; } ::if {![$Compiler chtml_page_tags_hit $Page]} { /* { We found the page but it is not a hit on the tags. We put out a a warning and return the text, but the link is disabled. */ } ::qw::warning 314120050519084214 "Help page \"$ThisPageId\" linked to page \"$TargetPageId\" that is not a hit on the tags."; ::return [::subst $Body]; } } ::if {$::qw::control(browser_help)} { #2.31.0 ::set Result "" ::append Result [::subst $Body]; ::append Result "" ::return $Result; } "" { ::append Result "$TargetPageId.htm"; ::if {[::sargs::get $s_args .bookmark] ne ""} { ::append Result "#[::sargs::get $s_args .bookmark]"; } ::append Result ">" ::append Result [::subst $Body]; ::append Result "" ::return $Result; } default { ::qw::throw \ .text "Couldn't link to page in invalid file \"$Chm\"." \ ; } } } else { ::set Result "" ::append Result [::subst $Body]; ::append Result "" #mk:@MSITStore:D:\Nv\demo_inv\nv2.dat\manual.chm::/314120050228112651.htm ::return $Result; } } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in link with args $args"]; } } method link_2_30_3 {args} { #ms-its:c:/rwb20_help_chm/nv2.chm::/314120040421124256.htm#314120040828145116 /* {

This should link to a page in the old help chm.

*/ } /* { Example in manual.qw_help to link to another page within manual. See the [link .id 150220040811161430 {[bold "Executive Summary"]}] for a brief overview. Example in error help to link to page in manual.chm (link is wrapped in list item). [li {[link .chm $::qw_manual_file .id 314120050422104251 {More on Versions and Updating}]}] The major difference is that the error help is dynamic and can find the chm file. Link Problem: Suppose a workshop chm includes a page from the manual that links to a another page that is in the manual but not the workshop. What we do is check whether the target page is a hit on the tags, and if it isn't then we do not attempt the link. If we could figure out the target chm file we could attempt the link but we still will not know what directory it will be in on a user machine. If we happen to know that the target page is also included in the workshop then we could link to that page in the workshop. This might actually work, but to do so we will have to manage the includes. The link to a page looks like: ...body... The link to bookmark 314120091231235959 within a page looks like: ...body... */ } ::qw::try { ::set s_args [::lrange $args 0 end-1]; ::set Body [::lindex $args end]; ::set TargetId [::sargs::get $s_args .id]; ::if {$TargetId eq ""} { ::qw::throw "Expected an \".id\"."; } ::set ThisPageId [qw_s_args .id]; ::set Compiler [qw_s_args .chtml.compiler]; ::if {$Compiler ne "" && ![::sargs::exists $s_args .chm]} { /* { We check to ensure the target page exists. However, if .chm is specified then the page is in another file and we cannot check. For example, we are linking from an error message into the manual. */ } ::set Page [$Compiler chtml_page_from_id $s_args]; ::if {$Page eq ""} { /* { The target page does not exist. */ } ::qw::throw "Help page \"$ThisPageId\" attempted to link to non-existing page \"$TargetId\"."; } ::if {![$Compiler chtml_page_tags_hit $Page]} { /* { We found the page but it is not a hit on the tags. We put out a a warning and return the text, but the link is disabled. */ } ::qw::warning 314120050519084214 "Help page \"$ThisPageId\" linked to page \"$TargetId\" that is not a hit on the tags."; ::return [::subst $Body]; } } ::set Result "" ::append Result [::subst $Body]; ::append Result "" #mk:@MSITStore:D:\Nv\demo_inv\nv2.dat\manual.chm::/314120050228112651.htm ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in link with args $args"]; } } method link_2.30.3 {args} { #ms-its:c:/rwb20_help_chm/nv2.chm::/314120040421124256.htm#314120040828145116 /* {

This should link to a page in the old help chm.

*/ } /* { Example in manual.qw_help to link to another page within manual. See the [link .id 150220040811161430 {[bold "Executive Summary"]}] for a brief overview. Example in error help to link to page in manual.chm (link is wrapped in list item). [li {[link .chm $::qw_manual_file .id 314120050422104251 {More on Versions and Updating}]}] The major difference is that the error help is dynamic and can find the chm file. Link Problem: Suppose a workshop chm includes a page from the manual that links to a another page that is in the manual but not the workshop. What we do is check whether the target page is a hit on the tags, and if it isn't then we do not attempt the link. If we could figure out the target chm file we could attempt the link but we still will not know what directory it will be in on a user machine. If we happen to know that the target page is also included in the workshop then we could link to that page in the workshop. This might actually work, but to do so we will have to manage the includes. The link to a page looks like: ...body... The link to bookmark 314120091231235959 within a page looks like: ...body... */ } ::qw::try { ::set s_args [::lrange $args 0 end-1]; ::set Body [::lindex $args end]; ::set TargetId [::sargs::get $s_args .id]; ::if {$TargetId eq ""} { ::qw::throw "Expected an \".id\"."; } ::set ThisPageId [qw_s_args .id]; ::set Compiler [qw_s_args .chtml.compiler]; ::if {$Compiler ne "" && ![::sargs::exists $s_args .chm]} { /* { We check to ensure the target page exists. However, if .chm is specified then the page is in another file and we cannot check. For example, we are linking from an error message into the manual. */ } ::set Page [$Compiler chtml_page_from_id $s_args]; ::if {$Page eq ""} { /* { The target page does not exist. */ } ::qw::throw "Help page \"$ThisPageId\" attempted to link to non-existing page \"$TargetId\"."; } ::if {![$Compiler chtml_page_tags_hit $Page]} { /* { We found the page but it is not a hit on the tags. We put out a a warning and return the text, but the link is disabled. */ } ::qw::warning 314120050519084214 "Help page \"$ThisPageId\" linked to page \"$TargetId\" that is not a hit on the tags."; ::return [::subst $Body]; } } ::set Result "" ::append Result [::subst $Body]; ::append Result "" #mk:@MSITStore:D:\Nv\demo_inv\nv2.dat\manual.chm::/314120050228112651.htm ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in link with args $args"]; } } /* { method link {args} { ::qw::try { ::set s_args [::lrange $args 0 end-1]; ::set Body [::lindex $args end]; ::if {[::sargs::get $s_args .id] eq ""} { ::qw::throw "Expected an \".id\"."; } ::append Result "" ::append Result [::subst $Body]; ::append Result "" ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in link with args $args"]; } } */ } method bookmark {args} { ::qw::try { ::set Body ""; ::if {[::expr {[::llength $args]%2}]} { /* { If odd args then body is last arg and first even-numbered args are the s_args. */ } ::set Body [::lindex $args end]; ::set args [::lrange $args 0 end-1]; } ::qw::s_args_marshal; # ::set s_args [::lrange $args 0 end-1]; # ::set Body [::lindex $args end]; ::if {[::sargs::get $s_args .id] eq ""} { ::qw::throw "Expected an \".id\"."; } ::append Result "" ::append Result [::subst $Body]; ::append Result "" ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in bookmark with args $args"]; } } method qw_include_file {args} { /* { Motivation: Areas like backing up are very similar if not identical in various manuals. So we want one copy of this common code. (1) Including a singlw page. (2) Including a page sub-structure. (3) Including text within a page. (4) Links */ } } method qw_include {args} { #ms-its:c:/cpp/manual/manual_nv2.chm::/314120040421124256.htm#314120040828145116 /* {

This should link to a page in the old help chm.

*/ } /* { We want to get the body of another page and render it in-line. What I would like to do is get the other page now and render it in this context. That would eliminate the need to actually process the page. But it has to be in the overall help structure. Motivation: We want to create a workshop manual that "includes" page from the user manual and does not require us to process the user manual. One way we can do this is to render the user manual but not eject its pages, based on tags. If it is necessary to render the included page then we have to process it and simply not Problem: If the included page has links to other pages that are not going to be produced, we will have dangling links. Solution (1) Produce the user and workshop manuals together. The link in the workshop will still link to the manual. (2) "unlink" all dangling links. */ } ::qw::try { /* { ::if {[::string first tag_workshop [qw_s_args .tags]]<0} { ::puts "_s_args==[::sargs::format .structure $_s_args]" ::puts "qw_s_args .tags==[qw_s_args .tags]" ::qw::bug 314120050713154627 "Encountered qw_include in non-workshop page with title [qw_s_args .title]." } */ } ::set s_args $args; ::set Id [::sargs::get $s_args .id]; ::if {$Id eq ""} { ::qw::throw "Encountered empty .id."; } ::set Compiler [qw_s_args .chtml.compiler]; ::if {$Compiler eq ""} { ::qw::throw "Called qw_include without a compiler."; } ::set Page [$Compiler chtml_page_from_id $s_args]; ::if {$Page eq ""} { ::qw::throw "Could not find page with id \"$Id\"."; } ::set Body [::sargs::get $Page .body]; ::set Result [::subst $Body]; ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in qw_include with args $args"]; } } method font_tag {args} { ::set Result ""; ::set Font [::sargs::get $args .font]; ::if {$Font eq ""} {::return $Result;} ::if {[::sargs::get $Font .size] ne ""} { ::append Result " font-size: [::sargs::get $Font .size]"; } ::if {[::sargs::get $Font .style] ne ""} { ::append Result " font-style: [::sargs::get $Font .style]"; } ::if {[::sargs::get $Font .family] ne ""} { ::append Result " font-family: [::sargs::get $Font .family]"; } ::if {[::sargs::get $Font .weight] ne ""} { ::append Result " font-weight: [::sargs::get $Font .weight]"; } } method common_table_attributes {s_args} { ::set Result ""; ::if {[::sargs::get $s_args .width] ne ""} { ::append Result " width=\"[::sargs::get $s_args .width]\""; } ::if {[::sargs::get $s_args .height] ne ""} { ::append Result " height=\"[::sargs::get $s_args .height]\""; } ::if {[::sargs::get $s_args .align] ne ""} { ::switch -- [::sargs::get $s_args .align] { center - char - top - bottom - left - right { } default { ::qw::throw "Could not recognize .align value \"[::sargs::get $s_args .align]\"."; } } ::append Result " align=\"[::sargs::get $s_args .align]\""; } ::return $Result; } method table {args} { /* { .border { .cellspacing .cellpadding } .width .height */ } ::set Tag table; ::qw::try { ::set Body [::lindex $args end]; # ::set Attributes [::lrange $args 0 end-1]; ::eval ::sargs::var::set Attributes [::lrange $args 0 end-1]; if {$Attributes ne "" && [::sargs::is_primitive $Attributes]} { ::qw::throw "Expected a well-formed list of name/value pairs."; } ::set Result "<$Tag"; ::set Border [::sargs::get $Attributes .border]; ::append Result " border"; ::set CellSpacing 0; ::set CellPadding 5; ::if {$Border ne ""} { ::if {[::sargs::get $Border .width] ne ""} { ::append Result "=[::sargs::get $Border .width]"; } ::if {[::sargs::get $Border .cellspacing] ne ""} { ::set CellSpacing [::sargs::integer_get $Border .cellspacing]; } ::if {[::sargs::get $Border .cellpadding] ne ""} { ::set CellPadding [::sargs::integer_get $Border .cellpadding]; } } ::append Result " cellspacing=\"$CellSpacing\""; ::append Result " cellpadding=\"$CellPadding\""; ::append Result [common_table_attributes $Attributes]; ::append Result ">\n"; ::append Result [list_to_string [::subst $Body]]; ::append Result "\n"; ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in $Tag method with args \"$args\"."]; } } method th {args} { /* { table row tag .width .height */ } ::set Tag th; ::qw::try { ::set Body [::lindex $args end]; ::set Attributes [::lrange $args 0 end-1]; ::set Result "<$Tag"; if {$Attributes ne "" && [::sargs::is_primitive $Attributes]} { ::qw::throw "Expected a well-formed list of name/value pairs."; } /* { ::if {[::sargs::get $Attributes .colspan] ne ""} { ::append Result " colspan=\"[::sargs::get $Attributes .colspan]\""; } ::if {[::sargs::get $Attributes .rowspan] ne ""} { ::append Result " rowspan=\"[::sargs::get $Attributes .rowspan]\""; } ::if {[::sargs::get $Attributes .valign] ne ""} { ::append Result " valign=\"[::sargs::get $Attributes .valign]\""; } */ } ::append Result [common_table_attributes $Attributes]; ::if {[::sargs::get $Attributes .rowspan] ne ""} { ::append Result " rowspan=\"[::sargs::get $Attributes .rowspan]\""; } ::if {[::sargs::get $Attributes .colspan] ne ""} { ::append Result " colspan=\"[::sargs::get $Attributes .colspan]\""; } ::if {[::sargs::get $Attributes .valign] ne ""} { ::append Result " valign=\"[::sargs::get $Attributes .valign]\""; } ::append Result ">\n"; ::append Result [list_to_string [::subst $Body]]; ::append Result "\n"; ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in $Tag method with args \"$args\"."]; } } method tr {args} { /* { table row tag .width .height */ } ::set Tag tr; ::qw::try { ::set Body [::lindex $args end]; ::set Attributes [::lrange $args 0 end-1]; if {$Attributes ne "" && [::sargs::is_primitive $Attributes]} { ::qw::throw "Expected a well-formed list of name/value pairs."; } ::set Result "<$Tag"; ::append Result [common_table_attributes $Attributes]; ::if {[::sargs::get $Attributes .rowspan] ne ""} { ::append Result " rowspan=\"[::sargs::get $Attributes .rowspan]\""; } ::if {[::sargs::get $Attributes .colspan] ne ""} { ::append Result " colspan=\"[::sargs::get $Attributes .colspan]\""; } ::if {[::sargs::get $Attributes .valign] ne ""} { ::append Result " valign=\"[::sargs::get $Attributes .valign]\""; } ::append Result ">\n"; ::append Result [list_to_string [::subst $Body]]; ::append Result "\n"; ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in $Tag method with args \"$args\"."]; } } method td {args} { /* { table cell ??? tag .width .height */ } ::set Tag td; ::qw::try { ::set Body [::lindex $args end]; ::set Attributes [::lrange $args 0 end-1]; if {$Attributes ne "" && [::sargs::is_primitive $Attributes]} { ::qw::throw "Expected a well-formed list of name/value pairs."; } ::set Result "<$Tag"; ::append Result [common_table_attributes $Attributes]; ::if {[::sargs::get $Attributes .rowspan] ne ""} { ::append Result " rowspan=\"[::sargs::get $Attributes .rowspan]\""; } ::if {[::sargs::get $Attributes .colspan] ne ""} { ::append Result " colspan=\"[::sargs::get $Attributes .colspan]\""; } ::if {[::sargs::get $Attributes .valign] ne ""} { ::append Result " valign=\"[::sargs::get $Attributes .valign]\""; } ::if {[::sargs::get $Attributes .align] ne ""} { ::switch -- [::sargs::get $Attributes .align] { center - char - top - bottom - left - right { } default { ::qw::throw "Could not recognize .align value \"[::sargs::get $Attributes .align]\"."; } } ::append Result " align=\"[::sargs::get $Attributes .align]\""; } ::append Result ">\n"; ::append Result [list_to_string [::subst $Body]]; /* { By adding a
we always put simething in the cell and therefore the borders will always be drawn. */ } ::append Result "
"; ::append Result "\n"; ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Encountered error in $Tag method with args \"$args\"."]; } } /* {

 

 

 

 

Format

Examples

mm/dd?/yy?

02/26/04 or 02/26

monthname dd ?,yy?

February 26, 04 or Feb 26, 04 or Feb 26

dd monthname ?yy?

26 February 04 or 26 Feb or 26 Feb

day, dd monthname yy

Thursday, 26 February 04 or Thu, 26 Feb 04

?CC?yymmdd

20040226 or 040226

?CC?yy-mm-dd

2004-02-26 or 04-02-26

dd-monthname-?CC?yy

26-February-2004 or 26-Feb-04

*/ } method bullets1 {args} { ::set Options ""; if {[::llength $args]>1} {::set Options [::lrange $args 0 [expr [::llength $args]-2]];} ::set List [list_to_string [::lrange $args end end]]; ::set Spaces 0; foreach {Option Value} $Options { switch -- $Option { "-spaces" {::set Spaces $Value;} default {error "Invalid bullets option $Option";} } } set Result "
    \n"; set Items "" foreach Item $List { set Item "
  • [::subst $Item]"; for {::set i -1} {$i<$Spaces} {incr i} {::append Item
    ;} ::lappend Items "$Item\n"; } ::append Result [list_to_string $Items]; ::append Result "
\n" return $Result; } method numbered1 {args} { ::set Options ""; if {[::llength $args]>1} {::set Options [::lrange $args 0 [expr [::llength $args]-2]];} ::set List [list_to_string [::lrange $args end end]]; ::set Spaces 0; foreach {Option Value} $Options { switch -- $Option { "-spaces" {::set Spaces $Value;} default {error "Invalid numbered option $Option";} } } set Result "
    \n"; set Items "" foreach Item $List { set Item "
  1. [::subst $Item]\n"; for {::set i -1} {$i<$Spaces} {incr i} {::append Item
    ;} ::lappend Items "$Item\n"; } ::append Result [list_to_string $Items]; ::append Result "
\n" return $Result; } method definitions1 {args} { ::set Options ""; if {[::llength $args]>1} {::set Options [::lrange $args 0 [expr [::llength $args]-2]];} ::set List [list_to_string [::lrange $args end end]]; ::set Spaces 0; foreach {Option Value} $Options { switch -- $Option { "-spaces" {::set Spaces $Value;} default {error "Invalid definitions option $Option";} } } set Result "
\n"; set Items "" foreach {Term Definition} $List { ::set Item "
$Term\n"; ::append Item "
$Definition\n"; for {::set i -1} {$i<$Spaces} {incr i} {::append Item
;} ::lappend Items "$Item\n"; } ::append Result [list_to_string $Items]; ::append Result "
\n" return $Result; } # -------------------------------------------------------- # custom methods # -------------------------------------------------------- method introduce {Arg} {::return [bold [italic $Arg]];} method qw_term {Arg} {::return [bold [italic $Arg]];} method qw_button {Arg} {::return "[bold [lt]$Arg[gt]]";} method qw_key {Arg} {::return "[bold [lt]$Arg[gt]]";} method qw_menu_command {args} {::return [bold [::join $args [gt]]];} method qw_field {Arg} {::return [bold [italic $Arg]];} method qw_field_name {Arg} {::return [bold [italic $Arg]];} method qw_field_value {Arg} {::return [bold [kbd $Arg]];} method qw_tab {Arg} {::return [big [bold [kbd $Arg]]];} method qw_directory_deprecated {Arg} {::return [bold [kbd $Arg]];} method qw_directory {args} { /* { 2.34.0 Would like to supply a single argument, i.e. the file/folder but this is often done as a variable such as [qw_file $Folder]. If the $Folder contains whitespace we're toast so it has to be wrapped such as {$Folder}. To avoid this we changed to args and if there is more than one arg we concatenate them together. */ } ::if {[::llength $args]>1} { ::set Args [::lindex $args 0]; ::foreach Arg [::lrange $args 1 end] { ::append Args " $Arg"; } ::return [bold [kbd $Args]]; } ::return [bold [kbd $args]]; } method qw_file {args} { /* { 2.34.11 qw_directory is two much typing and is unix-like. qw_file is simpler and more platform independent. */ } ::return [::eval qw_directory $args]; } method qw_quoted {Arg} {::return [quote]$Arg[quote];} method qw_bracketed {Arg} {::return [left_bracket]$Arg[right_bracket];} method qw_backslash {} {::return "\";} method qw_s_args {Path} { ::return [::sargs::get $_sargs $Path]; } method qw_sargs {Path} { ::return [::sargs::get $_sargs $Path]; } method qw_about_field {Arg} { ::return [bold [kbd [::subst $Arg]]]; } method nv1 {} {::return "NewViews version 1.0";} method nv2 {} {::return "NV2";} method qw {} {::return "QW Page";} method NewViews {} { return "NewViews[tm]"; } method qw_code_heading {Src} {::return "[bold [kbd $Src]][br]";} # -------------------------------------------------------- # wrap page # -------------------------------------------------------- method style_sheet {} { ::if {$::qw::control(browser_help)} { /* { # 2.31.0 Rather than put the css inline as we do with chm, we put the css file in htdocs/style_sheets and deliver it from the qw web server. Note that we also tried using a css file for chm but in the end it did not reduce the size of the resulting chm file. But it's worth it for browser_help because it reduces data transferred over internet. */ } ::return [::subst {}]; } /* { Next line seemed to work but didn't reduce chm file size so left original chm implementation as it was. #::return [::subst {}]; */ } ::if {$::qw::control(help_css_file) ne ""} { ::return $::qw::control(help_css_file); } ::set Style hp; ::set Style aspn.css; ::set Style qw; ::set Style aspn85.css; ::set Style aspn85_tpm.css; ::set Style aspn_docs; ::set Style none; ::set Style aspn_and_docs; ::set Style aspn_and_docs_228_2; ::set Result ""; ::append Result " } /* { The following sets styles according to the css (cascading style sheet) protocol. */ } /* { ::if {[::string tolower [::info hostname]] eq "borenste"} { ::return [::qw::script::source [::file join ]]; } */ } /* { ::if {[::string tolower [::info hostname]] eq "benn"} { ::return [::qw::script::source [::sargs .script.path [::file join c:/ cpp20 css.qw_script]]]; } */ } /* { ::if {[::string tolower [::info hostname]] eq "borenste"} { ::return [::qw::script::source [::sargs .script.path [::file join c:/ asb20 css.qw_script]]]; } */ } # ::set Result ""; ::append Result " body { font-family: Lucida Sans Unicode, Arial, Helvetica }\n" ::append Result " p { font-family: Arial, Helvetica; font-size: .8em; margin: 1em }\n" ::append Result " td { font-family: Arial, Helvetica; font-size: .8em; margin: 1em }\n" # ::append Result " p { font-family: Arial, Helvetica; font-size: 12pt; margin: 1em }\n" # ::append Result " h1 { font-size: 1.2em; font-weight: normal; color: #000000; background: #FFFF40; padding: 0.4em }\n" # ::append Result " h1 { font-size: 1.2em; font-weight: normal; color: #000000; background: red padding: 0.4em }\n" ::append Result " h1 { font-size: 1.2em; font-weight: normal; color: #000080; background: [::qw::color::symbol_to_rgb seashell2]; padding: 0.4em }\n" # ::append Result " h1 { font-size: 1.2em; font-weight: normal; color: #FFFFFF; background: blue; padding: 0.4em }\n" ::append Result " h2 { font-size: 1.0em; font-weight: normal; color: #000080; background: #DDDDDD; padding: 0.1em }\n" ::append Result " h3 { font-size: 0.8em; font-weight: normal; color: #000080; background: [::qw::color::symbol_to_rgb AntiqueWhite2]; padding: 0.1em }\n" # ::append Result " h3 { font-size: 0.8em; font-weight: normal; color: #000080; background: [::qw::color::symbol_to_rgb LemonChiffon1]; padding: 0.1em }\n" # ::append Result " h3 { font-size: 1.08em; font-weight: normal; color: #000080 background: blue; padding: 0.1em}\n" # ::append Result " h3 { font-size: 0.8em; font-weight: normal; color: #000080 background: blue; padding: 0.1em}\n" # ::append Result " h3 { font-size: 0.8em; font-weight: normal; color: #000080 }\n" ::append Result " h6 { font-size: 0.7em; font-weight: normal; margin: 1em }\n" ::append Result " em { font-size: 1em; font-weight: normal; font-style: normal; color: #000080 }\n" ::append Result " pre { color: black; margin: 1em 1em 1em 1em }\n" ::append Result " ul { font-family: Arial, Helvetica; font-size: 1.0em; margin: 1em 1em 1em 3em }\n" ::append Result " ol { font-family: Arial, Helvetica; font-size: 1.0em; margin: 1em 1em 1em 3em }\n" ::append Result " li { font-family: Arial, Helvetica; font-size: .8em}\n" ::append Result " li p { font-family: Arial, Helvetica; font-size: 1.0em}\n" ::append Result " ul li p { font-family: Arial, Helvetica; font-size: 1.0em}\n" # ::append Result " ul { font-family: Arial, Helvetica; font-size: 0.8em; margin: 1em 1em 1em 3em }\n" # ::append Result " li { font-family: Arial, Helvetica; font-size: 0.8em; margin: 1em 1em 1em 3em }\n" ::append Result " a { text-decoration: none }\n" ::append Result " a:hover { text-decoration: underline; color: red }\n" # ::append Result " img { float: right; clear: right; margin: .5em }\n" # ::return $Result; } "hp" { } aspn_and_docs_228_2 { ::return { } } aspn_and_docs { ::return { } } } ::append Result "-->\n" ::return $Result; } method page_wrap {s_args} { /* { Takes a page, wraps its body, and returns the page. Takes .title and .body and wraps it with a header, title and body tags. The body .text and .body arguments are not changed in any way. The real purpose of this method is to supply a title to html manipulators who use it, such as the HTML Help Workshop. */ } ::qw::try { ::set Title [::sargs::get $s_args .title]; ::if {$Title eq ""} { #::puts "Page without title,s_args==$s_args" ::qw::throw "Encountered a page without a title."; } ::set Body [::sargs::get $s_args .body]; ::set Result ""; ::append Result "\n"; ::append Result "\n"; ::append Result "\n"; ::append Result "$Title\n"; ::append Result "[style_sheet]\n"; ::append Result "\n"; ::append Result "\n"; ::append Result $Body; ::append Result "\n"; ::append Result "\n"; ::return [::sargs::set $s_args .body $Result]; ::return $Result; } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Could not wrap page with id \"[::sargs::get $s_args .id]\" and path \"[::sargs::get $s_args .path]\"."]; } } }; # ::qw::html::formatter ::proc ::qw::html::format {sargs} { /* { Usage: ::set Formatted [::qw::html::format .body $Body]; The entire $sargs are passed on to the formatter so they are offered to the qw_sargs command. */ } ::set Formatter [::qw::html::formatter ::qw::html::formatter::#auto]; ::qw::finally [::list ::itcl::delete object $Formatter]; ::set Page [$Formatter body_render $sargs]; ::return [::sargs::get $Page .body]; }