# http://benn7:8015/manual_nv2/2_30_3/main1.htm # file://c:/htdocs/manual_nv2/2_30_3/main1.htm # ------------------------------------------------------------ # Copyright (c) 2017-2017 # Q.W.Page Associates Inc. # www.qwpage.com # All rights reserved. # ------------------------------------------------------------ /* { Notes about paths. All files for a manual edition are placed in the same folder: c:/htdocs/manual_nv2/2_30_2 Each release has it's own folder. We didn't add release date to the folder so that we could change the date at the last minute without needing to rebuild the manual. Each page filename is $PageId.htm. The path to the file is therefore relative. Each image is an auto-incremented number with the image extension. Image tags can reference the image file using a relative path. */ } ::itcl::class ::qw::browser_tree_builder { protected variable _help_structure ""; # The help structure that we are compiling into a binary .chm file. protected variable _root_directory ""; # Directory of target compiled binary .chm file. protected variable _root_page_id ""; protected variable _initial_page_path ""; protected variable _directory ""; # Directory of target compiled binary .chm file. protected variable _name ""; # Name of target compiled binary .chm file. protected variable _path_list ""; # List of paths to every html page in the source help structure. protected variable _page_id_by_path_array; # Array of page ids indexed by page path. protected variable _bodies_by_path_array; # Array of formatted bodies indexed by page path. protected variable _chtml_title "NewViews Help"; protected variable _formatter ""; protected variable _generator "qw help generator"; protected variable _sargs ""; protected variable _command ""; # protected variable _url "benn7"; # http://benn7:8015/paned_demo2.htm protected variable _destination_folder ""; protected variable _source_folder ""; # protected variable _url_prefix "http://benn7:8015/manual_nv2/2_30_3"; protected variable _url_prefix ""; protected variable _rebuild_everything 1; protected variable _max_levels 1000; # i.e. infinity protected variable _html_extension htm; # protected variable _url_prefix "file://c:/htdocs/manual_nv2/2_30_3"; # protected variable _saved_current_directory ""; method constructor {} { ::array set _page_id_by_path_array {}; ::array set _bodies_by_path_array {}; } destructor { ::if {$_formatter ne ""} { ::itcl::delete object $_formatter; ::set _formatter ""; } } method process_pages {sargs} { /* { We start by getting a list of paths to every page in the help structure. Each page has a unique id obtained from its .id field, or for now, if there is no .id, it is generated from the structure field id. */ } ::set rwb1_debug 0; ::set PathList [::sargs::select_field .structure $_help_structure .field ".title"]; ::foreach Path $PathList { /* { We select only those pages that are a hit. */ } ::set Tags [::sargs::get $_help_structure ${Path}.tags]; ::if {[chtml_page_tags_hit [::sargs::get $_help_structure ${Path}]]} { ::lappend _path_list $Path; } } ::if {$rwb1_debug} { ::set i 0; ::foreach Path $_path_list { ::puts "rwb1_debug,2223.0,_path_list\[$i\]==$Path"; ::incr i; } } ::foreach Path $_path_list { # ::qw::warning "314120050324083416" "Encountered help page with no id,title==[::sargs::get $_help_structure $Path.title]"; ::if {[::sargs::get $_help_structure $Path.id] eq ""} { /* { Some pages forgot to set an .id so we set it from the last element in its path which should be unique id anyway. */ } ::sargs::var::set _help_structure $Path.id [::lindex [::split $Path /] end]; } /* { We now have a path. Set that path in the page. */ } ::sargs::var::set _help_structure $Path.path $Path; ::set Page [::sargs::get $_help_structure $Path]; ::set PageId [::sargs::get $Page .id]; # don't see how this is consistent with anything # ::if {[::info exists _page_id_by_path_array($PageId)]} {::qw::throw "Encountered duplicate page id \"$PageId\".";} ::if {$Path eq ""} { ::set Path "root"; ::set _root_page_id $PageId; } ::set _page_id_by_path_array($Path) $PageId; ::qw::try { ::sargs::var::+= Page $_sargs; ::if {$_rebuild_everything} { ::set RenderedPage [$_formatter page_render $Page]; } else { ::set RenderedPage $Page; } /* { ::sargs::var::set RenderedPage .body [::subst { This is page id - $PageId

Page Id $PageId

}]; */ } } catch Exception { ::qw::throw [::qw::exception::parent $Exception "Could not render the page identified by path \"$Path\"."]; } ::set _bodies_by_path_array($Path) [::sargs::get $RenderedPage .body]; } ::if {$rwb1_debug} { # ::puts "rwb1_debug,_help_structure==\n[::sargs::format $_help_structure]"; } ::if ${_rebuild_everything} { ::set CarcassList [::glob -nocomplain -- [::file join $_destination_folder *.*]]; ::foreach Carcass $CarcassList { ::file_delete -force -- Carcass; } ::foreach Path $_path_list { ::if {$Path eq ""} { ::set Path "root"; } ::set Handle [::open [::file join $_destination_folder $_page_id_by_path_array($Path).$_html_extension] w+]; ::puts -nonewline $Handle $_bodies_by_path_array($Path); ::close $Handle; } } } method check_images {} { /* { Gets the list of used images and the list of all images in the help folder and determines which ones are never actually used. Write these to a sub-folder. */ } ::return; ::set UsedImages ""; ::foreach {SrcPath DstName} [$_formatter images] { ::lappend UsedImages [::string tolower [::file tail $SrcPath]]; } ::set Folder [::file join c:/ qw_manual_216]; ::set ImagesInDirectory ""; ::foreach Pattern {*.jpg *.gif *.png *.bmp} { ::foreach Path [::glob [::file join $Folder $Pattern]] { ::lappend ImagesInDirectory [::string tolower [::file tail $Path]]; } } ::set Result [::qw::intersect3 $UsedImages $ImagesInDirectory]; ::set ImagesUsedButNotFound [::lindex $Result 0]; ::set UnusedImages [::lindex $Result 2]; ::puts "Images used but not found:" ::set Handle [::open [::file join $Folder images_used_but_not_found.txt] w+]; ::foreach Image $ImagesUsedButNotFound { ::puts "$Image"; ::puts $Handle "$Image"; } ::close $Handle; ::set OldFolder [::file join $Folder images_unreferenced]; ::file mkdir $OldFolder; ::puts "Images found but not used:" ::set Handle [::open [::file join $Folder images_unused.txt] w+]; ::foreach File $UnusedImages { ::puts $Handle "$File"; ::set Name [::file tail $File]; ::puts "Moving and deleting $File"; ::file copy -force [::file join $Folder $File] [::file join $OldFolder $Name]; ::file delete -force -- [::file join $Folder $File]; } /* { ::foreach Image $UnusedImages { ::puts $Handle "$Image"; ::set Name [::file tail $Image]; ::set Files [::glob -nocomplain [::file join $Folder [::file rootname $Image]].*]; ::foreach File $Files { ::puts "Moving and deleting $File"; ::file copy -force $File [::file join $OldFolder [::file tail $File]]; ::file delete -force -- File; } } */ } } method generate_webpage_header {} { /* { */ } /* { defaults: { resizable: true } */ } /* { The following was working. We then copied them all into htdocs/jquery 2.38.0 The following link stopped working. http://layout.jquery-dev.com/lib/js/jquery.layout-latest.js Replaced it with the following link: https://cdnjs.cloudflare.com/ajax/libs/jquery-layout/1.4.3/jquery.layout.min.js Ward found the problem and the solution. */ } ::set WindowTitle [::sargs::get $_sargs .window_title]; ::if {$WindowTitle eq ""} { ::set WindowTitle "NewViews Help"; } ::return [::subst { $WindowTitle }]; } method generate_webpage_footer {} { /* { We set the event listener on the root item in the help tree. This item is a LI element and all other LI elements are below it in the DOM tree. Therefore the root receives all events. Otherwise we would need a separate listener on every LI node in the tree. */ } ::set PageId $_root_page_id; ::set OnScripts [::subst -nocommands { jQuery('#$PageId').click(function(Event) { var Current=this; /* current - is the elelent the event handler was attached to target - the mouse clicked on this element */ var Target=Event.target; var PageId=Target.id.substr(0,Target.id.indexOf("_")); var Element=jQuery('#'+PageId)[0]; /* We have the element. Now let's use ajax to load it. Note that we have to put in some checks. The element is an LI and maybe we could add a class or other local information to help identify it. */ var Url='$_url_prefix/'+Element.id+'.$_html_extension'; jQuery('#center_pane').attr("src",Url); }); }]; ::return [::subst -nocommands { }]; } method generate_center_pane {} { ::return {

The Center Pane

The right of the people to be secure in their persons, houses, papers, and effects against unreasonable searches and seizures shall not be violated, and no Warrants shall issue but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched and the persons or things to be seized.

} } method generate_north_pane {} { ::return {

The North Pane

The right of the people to be secure in their persons, houses, papers, and effects against unreasonable searches and seizures shall not be violated, and no Warrants shall issue but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched and the persons or things to be seized.

} } method generate_east_pane_save {} { ::return {

The East Pane

The right of the people to be secure in their persons, houses, papers, and effects against unreasonable searches and seizures shall not be violated, and no Warrants shall issue but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched and the persons or things to be seized.

} } method generate_east_pane {} { ::return {

The East Pane

The right of the people to be secure in their persons, houses, papers, and effects against unreasonable searches and seizures shall not be violated, and no Warrants shall issue but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched and the persons or things to be seized.

} } method generate_west_pane {} { ::return {

The West Pane

The right of the people to be secure in their persons, houses, papers, and effects against unreasonable searches and seizures shall not be violated, and no Warrants shall issue but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched and the persons or things to be seized.

} } method generate_south_pane {} { ::return {

The South Pane

The right of the people to be secure in their persons, houses, papers, and effects against unreasonable searches and seizures shall not be violated, and no Warrants shall issue but upon probable cause, supported by Oath or affirmation, and particularly describing the place to be searched and the persons or things to be seized.

} } method generate_multipane_webpage {sargs} { ::set rwb1_debug 0; /* { This is the content of the main page. */ } # ------------------------------------------------------------ # Root page (in addition to being a branch page) # ------------------------------------------------------------ ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.0";} ::set WebPage ""; ::append WebPage [generate_webpage_header]; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.1";} /* { ::append WebPage [::subst {
$HelpTree
}] */ } ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.2";} ::append WebPage [::subst {
[generate_help_tree]
}]; /* { ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.3";} ::append WebPage [::subst {
[generate_north_pane]
}]; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.4";} ::append WebPage [::subst {
[generate_south_pane]
}]; */ } ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.5,_root_page_id==$_root_page_id";} /* { ::append WebPage [::subst {

Is anything going to show up around here?

}]; */ } /* { */ } /* { We start by putting the root page in the "right" pane. */ } ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.6.0,_initial_page_path==$_initial_page_path";} ::if {$_initial_page_path eq ""} { ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.6.1";} ::set _initial_page_path "/${_root_page_id}.$_html_extension"; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.6.2";} } ::append WebPage [::subst { }]; /* { ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.6";} ::append WebPage [::subst {
[generate_west_pane]
}]; */ } ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.7";} ::append WebPage [generate_webpage_footer]; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.8";} # ::append WebPage $HelpTree; # ::append WebPage $HelpPage; # ::append WebPage $MultipaneFooter; ::set FilePath [::file join $_destination_folder main1.$_html_extension] ::set Handle [::open $FilePath w+]; ::puts -nonewline $Handle "$WebPage"; ::close $Handle; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_multipane,1000.9";} } method generate_help_tree {sargs} { /* { Usage: generate_help_tree .path $Path .level $Level; .path - path to current tree node. Empty implies root page. .level - current level in tree, used when debugging to limit depth for faster turnaround Creates a hierarchy using ul and li tags. */ } /* { Once an instance is ready you can invoke methods on it. There is a list of available methods in the API documentation. The three examples below do exactly the same thing: jQuery('button').on('click', function () { jQuery('#jstree').jstree(true).select_node('child_node_1'); jQuery('#jstree').jstree('select_node', 'child_node_1'); $.jstree.reference('#jstree').select_node('child_node_1'); }); class="jstree-open" */ } ::set rwb1_debug 0; ::set Icon "https://www.jstree.com/tree.png"; ::set Icon "$_url_prefix/jstree/images/moTreeC.gif"; #rwb_debug - rwb_todo we have to fix this, maybe copy into destination folder # may have to come out of the vfs ::set Icon "file://c:/htdocs/jstree/images/moTreeC.gif"; ::set Path [::sargs::get $sargs .path]; ::set Level [::sargs::integer_get $sargs .level]; /* { ::switch -- $_url { "benn7" { ::set Icon "http://benn7:8015/jstree/images/moTreeC.gif"; } default { ::set Icon "file://c:/htdocs/jstree/images/moTreeC.gif"; } } */ } ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.0";} ::if {$Path eq ""} { ::set SubNameList [::sargs::subs .structure $_help_structure]; } else { ::set SubNameList [::sargs::subs .structure [::sargs::get $_help_structure $Path]]; } ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.1";} ::set Result ""; ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.2";} ::set Title [::sargs::get $_help_structure $Path.title]; ::set PageId [::sargs::get $_help_structure $Path.id]; ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.3,Path==$Path";} # onclick="alert('Page $PageId about to load');jQuery('center_pane').load('file://c:/htdocs/web_manual/$PageId.htm');" # onclick="console.log('Page $PageId about to load');" # onclick="jQuery('#center_pane').load('file://c:/htdocs/web_manual/$PageId.htm');" ::if {$Level>=$_max_levels||[::llength $SubNameList]==0} { # ------------------------------------------------------------ # Leaf page. # ------------------------------------------------------------ ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.4";} ::if {$Path eq ""} { # ------------------------------------------------------------ # Root leaf page. # ------------------------------------------------------------ /* { Leaf page that is also root. Only one page in the tree. */ } ::append Result [::subst { }]; ::return $Result; } # ------------------------------------------------------------ # Non-root leaf page. # ------------------------------------------------------------ /* { Leaf page that is also root. Root slightly different because it is given class "jstree-open", so it will be expanded. */ } ::append Result [::subst {
  • $Title
  • }]; ::append Result "\n"; ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.5";} ::return $Result; } ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.6";} ::if {$Path eq ""} { # ------------------------------------------------------------ # Root branch page. # ------------------------------------------------------------ /* { Branch page that is also root. Root slightly different because it is given class "jstree-open", so it will be expanded. */ } ::append Result " }]; ::return $Result; /* { ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.8";} ::append Result [::subst {
  • $Title }]; */ } } # ------------------------------------------------------------ # Non-root branch page. # ------------------------------------------------------------ ::append Result [::subst {
  • $Title }]; ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.9";} ::append Result "\n"; ::append Result "
  • \n"; ::if {$rwb1_debug} {::puts "rwb1_debug,jstree_generate,1000.12";} ::return $Result; } method generate_images {} { ::set rwb1_debug 0; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.0,_source_folder==$_source_folder,_destination_folder==$_destination_folder";} #rwb1_debug,generate_images,1000.0,_source_folder==C:/rwb/object/newviews/account,_destination_folder==c:/temp/qwpage/39CB94654FB4FC64 check_images; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.1";} /* { 2.31.0 We know we are generating a manual so the files are coming from a source folder and being copied to a destination folder. For now we just copy them to the destination folder using the file name. In the future we should be able to distinguish between images that should be copied to the destination folder and those which are "global" in nature, i.e. can be loaded from somewhere else on the net. Or they could be shared by multiple manual versions, say from a common folder somewhere on the server. */ } ::if {!$_rebuild_everything} { ::return; } ::qw::try { ::set FormatterImageList [$_formatter images]; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.1.0,FormatterImageList==$FormatterImageList";} ::if {[::llength $FormatterImageList]==0} { ::return; } ::if {$_source_folder eq ""} { ::qw::throw \ .text "Document has images but no .source_folder argument." \ .error_id 314120170207140214 \ ; } ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.2";} ::foreach {SrcPath DstName} $FormatterImageList { ::set DstName [::file tail $DstName]; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.3,SrcPath==$SrcPath,DstName==$DstName";} ::switch -- [::file pathtype $SrcPath] { "relative" { ::qw::try { ::set SrcPath [::file join $_source_folder $SrcPath]; ::set DstPath [::file join $_destination_folder $DstName]; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.3";} ::file copy -force $SrcPath $DstPath; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.4";} } catch Exception { ::qw::throw [::qw::exception::nest .sub $Exception .super "Could not copy image file \"$SrcPath\" to \"$DstPath\"."]; } } "absolute" { ::qw::try { ::set DstPath [::file join $_destination_folder $DstName]; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.5,SrcPath==$SrcPath,DstPath==$DstPath";} ::file copy -force $SrcPath $DstPath; ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.6";} } catch Exception { ::qw::throw [::qw::exception::nest .sub $Exception .super "Could not copy image file \"$SrcPath\" to \"$DstPath\"."]; } } default { ::qw::throw "Encountered absolute path $SrcPath"; } } } } catch Exception { ::qw::throw [::qw::exception::nest .sub $Exception .super [::sargs \ .text "Could not generate the images." \ ]]; } ::if {$rwb1_debug} {::puts "rwb1_debug,generate_images,1000.7";} } method chtml_page_from_id {s_args} { /* { Added this for the formatter include method. The formatter must be able to load the page so that it can extract the body for the include. */ } ::set Id [::sargs::get $s_args .id]; ::set Paths [::sargs::select_field_value .structure $_help_structure .field .id .value $Id]; ::switch -- [::llength $Paths] { 0 { ::return ""; } 1 { ::return [::sargs::get $_help_structure [::lindex $Paths 0]]; } } ::qw::throw "Expected one page with id \"$Id\" but encountered \"$Paths\""; } method chtml_block_tags_hit {sargs} { /* { We could send the caller args on to the formatter but instead we have the formatter call back to this object which in turn has the block_tags_hit callback. This is called back from tagged_block command (really a div with .block_tags argument). */ } #rwb_debug see if this is necessary ::qw::throw "rwb_debug,314120190729114505,chtml_block_tags_hit,not used yet."; } method chtml_page_tags_hit {sargs} { /* { The qw_chtml_compile caller provides a .page_is_hit script. This script is evaluated using ::subst and should return 0 or 1. If the script is empty then 1 is assumed. The help page is a structure passed to chtml_page_tags_hit as sargs and the callback script has access to sargs; which is the entire page structure. It usually examines .tags but it can examine anything in the page. We get the script from the original arguments passed to chtml_compile, which are stored in _sargs. Actually I believe the callback has access to _sargs as well. See qw_compiler.qw_lib for documentation because this a copy of the same method. */ } ::set Script [::sargs::get $_sargs .page_is_hit]; ::if {$Script eq ""} { return 1; } ::set Result [::subst $Script]; ::return $Result; } method main {sargs} { /* { .destination_folder - we build the result here The "result" is a set of files, one per page. Each file name is the page id and the extension .htm. .source_folder We get the images from this folder and copy them into the destination folder. If there are images then the source folder must be specified. Otherwise it is optional. .root_folder Used as prefix for and src attributes. .initial_page_path /314120121017155245.htm Used by auto_reconcile.qw_script to position on a specific initial page after launching. How is the result delivered to the user? This could be the manual, in which case a web server will deliver the result to the user. If this is help on a prompt or error, or is a report such as a semiloop report or an auto-reconcile report, then it must be displayed immediately in a browser. This can be done in one of two ways: (1) Content is delivered by a local web server on a known port and it's default htdocs is set to the destination folder. Unfortunately the tclhttpd can only have one instance per process. An alternative is to use a light-weight server that can be instantiated. (2) Content is delivered by a local browser using files in the tags. The formatter must be supplied with a prefix that can be used on all img and tags, i.e. file://c:/temp/314120170207104835 Problem: Currently using local files for some js libraries. ------------------------------------------------------------------------ .name .directory This is the target for the binary .chm file that will be generated. A file with the specified name with extension .chm appended is placed in the specified directory only if everything succeeds. Note that the ultimate copy to this file can fail if for example the help system is currently running on an already existing target .chm file. .help This is the actual help structure. It must be gathered up using other tools before calling the compiler. The compiler takes a help structure and generates a .chm file, i.e. a Microsoft html help binary, for that structure. The target .chm file is placed in the specified directory and given the specified name. The compiler generates the source files needed by hhc.exe, the Microsoft chtml help compiler. hhc.exe works on files so we have to create a temporary directory which we call he project directory. Within the project directory we create: project.hhp The html help project file. project.hhc The htnl help contents file. project.hhk The html help index file. project.chm The html target binary. For each page we create a file whose name is the page id and whose extension is .htm. When we are done we copy the target .chm file to the specified directory and name and keep the extension .chm. For now we clean up the project directory at the beginning of a compile and leave it alone for debug purposes. Later we will clean up after the compile. For now, the project directory is hardwired to c:/htmlhelptst. The pages in the .ctm file can be specified using topics where a topic is the help page id followed by the extension .htm. returns the name of generated .chm file. */ } ::set rwb1_debug 0; ::if {$rwb1_debug} {::puts "rwb1_debug,compiler,main.1000.0,sargs==\n[::sargs::format $sargs]";} ::if {$rwb1_debug} {::puts "rwb1_debug,compiler,main.1000.1";} ::set _sargs $sargs; ::sargs::var::set _sargs .chtml.compiler $this; ::set _directory [::sargs::get $sargs .directory]; ::set _root_directory [::sargs::get $sargs .path]; ::set _source_folder [::file dirname [::sargs::get $sargs .source_folder]]; ::set _initial_page_path [::sargs::get $sargs .initial_page_path]; ::set _source_folder [::sargs::get $sargs .source_folder]; ::set _destination_folder [::sargs::get $sargs .destination_folder]; ::if {$rwb1_debug} {::puts "rwb1_debug,compiler,main.1000.2,_source_folder==$_source_folder,_destination_folder==$_destination_folder";} #rwb1_debug,compiler,main.1000.2,_source_folder==C:/rwb/object/newviews/account,_destination_folder==c:/temp/qwpage/96052E92BE191E0C ::set _name [::sargs::get $sargs .name]; ::set _help_structure [::sargs::get $sargs .structure]; #rwb_debug have to set this to a value for building the manual itself. ::set _url_prefix [::sargs::get $sargs .url_prefix]; ::if {$_source_folder eq ""} { /* { The exception is only thrown in generate_images because we really need a source folder only if there are in fact images to process. */ } #::qw::throw "No .source_folder argument."; } /* { The source folder is only needed for images. If not cuppies then there should be no images. */ } ::if {$_source_folder ne ""} { ::if {[::file exists $_source_folder]} { ::if {![::file isdirectory $_source_folder]} { ::qw::throw \ .text "Expected $_source_folder to be a folder." \ ; } # ::qw::throw \ # .text "$_source_folder does not exist." \ # ; } } ::if {$_destination_folder eq ""} { ::qw::throw \ .text "No .destination_folder argument." \ ; } ::if {![::file exists $_destination_folder]} { ::qw::throw \ .text "$_destination_folder does not exist." \ ; } ::if {![::file isdirectory $_destination_folder]} { ::qw::throw \ .text "Expected $_destination_folder to be a folder." \ ; } ::set _formatter [::qw::html::formatter #auto .root_directory $_root_directory .compiler $this]; ::set _command [::sargs::get $sargs .compiler.command]; ::if {[::sargs::get $sargs .window_title] ne ""} { ::set _chtml_title [::sargs::get $sargs .window_title]; } /* { We will copy/build all files in the destination folder. The next line creates the folder if it doesn't already exist. */ } ::qw::fileutil::mkdir .path $_destination_folder; # ::if {$_directory eq ""} {::qw::throw "Encountered an empty .directory argument.";} # ::if {$_name eq ""} {::qw::throw "Encountered an empty .name argument.";} ::if {$_directory eq ""} { ::set _directory [::file normalize [::qw::fileutil::temporary_path .prefix "qwpage_" .suffix ".tmp"]]; } ::if {$_name eq ""} { ::set _name [::file tail [::file normalize [::qw::fileutil::temporary_path .directory $_directory .prefix "qw_page_"]]]; } ::if {$_help_structure eq ""} { ::qw::throw "Encountered an empty .help argument."; } ::if {$rwb1_debug} {::puts "rwb1_debug,compiler,main.1000.6";} process_pages; ::if {$rwb1_debug} {::puts "rwb1_debug,compiler,main.1000.7";} generate_images; ::if {$rwb1_debug} {::puts "rwb1_debug,compiler,main.1000.8";} generate_multipane_webpage ::if {$rwb1_debug} {::puts "rwb1_debug,compiler,main.1000.99";} # jstree_generate ""; # generate_json_fancytree ""; } }