Index: library/lib/doc-assets/class.html.tmpl =================================================================== diff -u -rdbddbce63d4a499de52ff07fdc63c02017960c79 -r5f765b6d8713f416a443cc2367c3a47903cc2f83 --- library/lib/doc-assets/class.html.tmpl (.../class.html.tmpl) (revision dbddbce63d4a499de52ff07fdc63c02017960c79) +++ library/lib/doc-assets/class.html.tmpl (.../class.html.tmpl) (revision 5f765b6d8713f416a443cc2367c3a47903cc2f83) @@ -22,7 +22,7 @@ }]
- [:text] + [:as_text]
@@ -37,7 +37,7 @@
- [$attr text] + [$attr as_text]
@@ -103,7 +103,7 @@
- [$attr text] + [$attr as_text]
@@ -151,7 +151,7 @@
Method is redefine-protected }]
- [$method text] + [$method as_text]
@@ -164,7 +164,7 @@ [$param name] [:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}] - [$param text] + [$param as_text] [:? {[$param eval {info exists :default}]} {
Default Value: [$param default] @@ -181,7 +181,7 @@
Returns:
-
[$rparam text]
+
[$rparam as_text]
}] @@ -256,7 +256,7 @@ [$omethod parameters]
- [$omethod text] + [$omethod as_text]
@@ -269,7 +269,7 @@ [$param name] [:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}] - [$param text] + [$param as_text] }] @@ -281,7 +281,7 @@
Returns:
-
[$rparam text]
+
[$rparam as_text]
}] Index: library/lib/doc-assets/command.html.tmpl =================================================================== diff -u -r6458c13882afd52e8719ee0e0e054b42e9aee696 -r5f765b6d8713f416a443cc2367c3a47903cc2f83 --- library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision 6458c13882afd52e8719ee0e0e054b42e9aee696) +++ library/lib/doc-assets/command.html.tmpl (.../command.html.tmpl) (revision 5f765b6d8713f416a443cc2367c3a47903cc2f83) @@ -4,7 +4,7 @@
- [:text] + [:as_text]
@@ -41,7 +41,7 @@ [$sub parameters]
- [$sub text] + [$sub as_text] [:? {[$sub eval {info exists :@param}]} {
Subcommand parameters:
@@ -50,7 +50,7 @@ [$param name] [:? {[$param eval {info exists :spec}] && [$param spec] ne ""} {<[$param spec]>}] - [$param text] + [$param as_text] }]
@@ -60,7 +60,7 @@
Returns:
-
[[$sub @return] text]
+
[[$sub @return] as_text]
}]
@@ -80,7 +80,7 @@ [$param name] <[:? {[$param eval {info exists :spec}]} {[$param spec]}]> - [$param text] + [$param as_text] }] @@ -91,7 +91,7 @@
Returns:
-
[${:@return} text]
+
[${:@return} as_text]
}] }] Index: library/lib/doc-assets/package.html.tmpl =================================================================== diff -u -rdbddbce63d4a499de52ff07fdc63c02017960c79 -r5f765b6d8713f416a443cc2367c3a47903cc2f83 --- library/lib/doc-assets/package.html.tmpl (.../package.html.tmpl) (revision dbddbce63d4a499de52ff07fdc63c02017960c79) +++ library/lib/doc-assets/package.html.tmpl (.../package.html.tmpl) (revision 5f765b6d8713f416a443cc2367c3a47903cc2f83) @@ -4,7 +4,7 @@
- [:text] + [:as_text]
Index: library/lib/doc-tools.tcl =================================================================== diff -u -rcabb7fe9c303839d53970b59262f9ae416aef2eb -r5f765b6d8713f416a443cc2367c3a47903cc2f83 --- library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision cabb7fe9c303839d53970b59262f9ae416aef2eb) +++ library/lib/doc-tools.tcl (.../doc-tools.tcl) (revision 5f765b6d8713f416a443cc2367c3a47903cc2f83) @@ -383,7 +383,8 @@ set r [dict create] # puts stderr SLOTS=$slots foreach s $slots { - if {![$s info is type ::nx::doc::PartAttribute] || ![$s eval {info exists :part_class}]} continue; + # [$s info is type ::nx::doc::PartAttribute] + if {![::nsf::objectproperty $s type ::nx::doc::PartAttribute] || ![$s eval {info exists :part_class}]} continue; set accessor [$s name] # puts stderr "PROCESSING ACCESSOR $accessor, [info exists :$accessor]" if {[info exists :$accessor]} { @@ -424,19 +425,22 @@ # performs substitution on it. The substitution is not essential, # but looks for now convenient. # - :method text {-as_list:switch} { + + :method as_list {} { if {[info exists :@doc] && ${:@doc} ne ""} { - set doc ${:@doc} - set non_empty_elements [lsearch -all -not -exact $doc ""] - set doc [lrange $doc [lindex $non_empty_elements 0] [lindex $non_empty_elements end]] - if {$as_list} { - return $doc - } else { - return [subst [join $doc " "]] - } + set non_empty_elements [lsearch -all -not -exact ${:@doc} ""] + return [lrange ${:@doc} [lindex $non_empty_elements 0] [lindex $non_empty_elements end]] } } + :method as_text {} { + set doc [list] + foreach l [:as_list] { + lappend doc [string trimleft $l] + } + return [subst [join $doc " "]] + } + :method filename {} { return [[:info class] tag]_[string trimleft [string map {:: __} ${:name}] "_"] } @@ -846,7 +850,40 @@ namespace eval ::nx::doc { - Class create TemplateData { + Class create TemplateDataClass -superclass Class { + :method find_asset_path {{-subdir library/lib/doc-assets}} { + # This helper tries to identify the file system path of the + # asset ressources. + # + # @param -subdir Denotes the name of the sub-directory to look for + foreach dir $::auto_path { + set assets [file normalize [file join $dir $subdir]] + if {[file exists $assets]} { + return $assets + } + } + } + + :method read_tmpl {path} { + if {[file pathtype $path] ne "absolute"} { + set assetdir [:find_asset_path] + set tmpl [file join $assetdir $path] + } else { + set tmpl [file normalize $path] + } + if {![file exists $tmpl] || ![file isfile $tmpl]} { + error "The template file '$path' was not found." + } + set fh [open $tmpl r] + set content [read $fh] + catch {close $fh} + return $content + } + + } + + + TemplateDataClass create BaseTemplateData { # This mixin class realises a rudimentary templating language to # be used in nx::doc templates. It realises language expressions # to verify the existence of variables and simple loop constructs @@ -915,136 +952,157 @@ uplevel 1 [list subst [[::nsf::current class] read_tmpl $template]] } - # - # TODO: This should turn into a hook, the output - # specificities should move in a refinement of TemplateData, e.g., - # DefaultHtmlTemplateData or the like. - # - :method fit {str max {placeholder "..."}} { - if {[llength [split $str ""]] < $max} { - return $str; - } - set redux [llength [split $placeholder ""]] - set margin [expr {($max-$redux)/2}] - return "[string range $str 0 [expr {$margin-1}]]$placeholder[string range $str end-[expr {$margin+1}] end]" + :method code args { + error "Subclass responsibility: You must provide a method definition of '[current method]' in a proper subclass" } - :method list_structural_features {} { - set entry {{"access": "$access", "host": "$host", "name": "$name", "url": "$url", "type": "$type"}} - set entries [list] - if {[:info is type ::nx::doc::@package]} { - set features [list @object @command] - foreach feature $features { - set instances [sorted [$feature info instances] name] - foreach inst $instances { - set access "" - set host [:name] - set name [$inst name] - set url "[$inst filename].html" - set type [$feature tag] - lappend entries [subst $entry] - } + :method link args { + error "Subclass responsibility: You must provide a method definition of '[current method]' in a proper subclass" + } + + set :markup_map(sub) { + "{{{" "\[:code \{" + "}}}" "\}\]" + "{{" "\[:link " + "}}" "\]" + } + + set :markup_map(unescape) { + "\\{" "{" + "\\}" "}" + "\\#" "#" + } + + :method map {line set} { + set line [string map [[::nsf::current class] eval [list set :markup_map($set)]] $line] + } + + :method as_list {} { + set preprocessed [list] + set is_code_block 0 + foreach line [next] { + if {[regsub -- {^\s*(\{\{\{)\s*$} $line "\[:code -inline false \{" line] || \ + (${is_code_block} && [regsub -- {^\s*(\}\}\})\s*$} $line "\}\]" line])} { + set is_code_block [expr {!$is_code_block}] + append line \n + } elseif {${is_code_block}} { + # set line [:map $line unescape] + append line \n + } else { + # set line [:map $line sub] + # set line [:map $line unescape] + set line [string trimleft $line] + if {$line eq {}} { + set line "\n\n" + } + } + lappend preprocessed $line } - } elseif {[:info is type ::nx::doc::@object]} { - # TODO: fix support for @object-method! - set features [list @method @param] - foreach feature $features { - if {[info exists :$feature]} { - set instances [sorted [:$feature] name] + return $preprocessed + } + + :method as_text {} { + set preprocessed [join [:as_list] " "] + set preprocessed [:map $preprocessed sub] + set preprocessed [:map $preprocessed unescape] + return [subst $preprocessed] + } + + } + + # + # A default TemplateData implementation, targeting the derived YUI + # Doc templates. + # + + TemplateDataClass create NxDocTemplateData -superclass BaseTemplateData { + :method fit {str max {placeholder "..."}} { + if {[llength [split $str ""]] < $max} { + return $str; + } + set redux [llength [split $placeholder ""]] + set margin [expr {($max-$redux)/2}] + return "[string range $str 0 [expr {$margin-1}]]$placeholder[string range $str end-[expr {$margin+1}] end]" + } + + :method list_structural_features {} { + set entry {{"access": "$access", "host": "$host", "name": "$name", "url": "$url", "type": "$type"}} + set entries [list] + if {[:info is type ::nx::doc::@package]} { + set features [list @object @command] + foreach feature $features { + set instances [sorted [$feature info instances] name] foreach inst $instances { - set access [expr {[info exists :@modifier]?[:@modifier]:""}] + set access "" set host [:name] set name [$inst name] - set url "[:filename].html#[$feature tag]_[$inst name]" + set url "[$inst filename].html" set type [$feature tag] lappend entries [subst $entry] } } - } - } elseif {[:info is type ::nx::doc::@command]} { - set features @subcommand - foreach feature $features { - if {[info exists :$feature]} { - set instances [sorted [set :$feature] name] - foreach inst $instances { - set access "" - set host ${:name} - set name [$inst name] - set url "[:filename].html#[$feature tag]_[$inst name]" - set type [$feature tag] - lappend entries [subst $entry] + } elseif {[:info is type ::nx::doc::@object]} { + # TODO: fix support for @object-method! + set features [list @method @param] + foreach feature $features { + if {[info exists :$feature]} { + set instances [sorted [:$feature] name] + foreach inst $instances { + set access [expr {[info exists :@modifier]?[:@modifier]:""}] + set host [:name] + set name [$inst name] + set url "[:filename].html#[$feature tag]_[$inst name]" + set type [$feature tag] + lappend entries [subst $entry] + } } } + } elseif {[:info is type ::nx::doc::@command]} { + set features @subcommand + foreach feature $features { + if {[info exists :$feature]} { + set instances [sorted [set :$feature] name] + foreach inst $instances { + set access "" + set host ${:name} + set name [$inst name] + set url "[:filename].html#[$feature tag]_[$inst name]" + set type [$feature tag] + lappend entries [subst $entry] + } + } + } } + return "\[[join $entries ,\n]\]" } - return "\[[join $entries ,\n]\]" - } - - :method code {{-inline true} script} { - return [expr {$inline?"$script":"
$script
"}] - } - - :method link {entity_type args} { - set id [$entity_type id {*}$args] - if {![::nsf::is $id object]} return; - set pof "" - if {[$id info is type ::nx::doc::Part]} { - set pof "[[$id partof] name]#" - set filename [[$id partof] filename] - } else { - set filename [$id filename] + + # + # TODO: This should turn into a hook, the output + # specificities should move in a refinement of TemplateData, e.g., + # DefaultHtmlTemplateData or the like. + # + + :method code {{-inline true} script} { + return [expr {$inline?"$script":"
$script
"}] } - return "$pof[$id name]" - } - - :method text {} { - # Provide \n replacements for empty lines according to the - # rendering frontend (e.g., in HTML ->
) ... - if {[info exists :@doc]} { - set doc [next -as_list] - foreach idx [lsearch -all -exact $doc ""] { - lset doc $idx "

" + + :method link {entity_type args} { + set id [$entity_type id {*}$args] + if {![::nsf::is $id object]} return; + set pof "" + if {[$id info is type ::nx::doc::Part]} { + set pof "[[$id partof] name]#" + set filename [[$id partof] filename] + } else { + set filename [$id filename] } - return [subst [join $doc " "]] + return "$pof[$id name]" } - } - - - - # - # - # - - :object method find_asset_path {{-subdir library/lib/doc-assets}} { - # This helper tries to identify the file system path of the - # asset ressources. - # - # @param -subdir Denotes the name of the sub-directory to look for - foreach dir $::auto_path { - set assets [file normalize [file join $dir $subdir]] - if {[file exists $assets]} { - return $assets - } + + :method as_text {} { + return [string map {"\n\n" "

"} [next]] } } - - :object method read_tmpl {path} { - if {[file pathtype $path] ne "absolute"} { - set assetdir [:find_asset_path] - set tmpl [file join $assetdir $path] - } else { - set tmpl [file normalize $path] - } - if {![file exists $tmpl] || ![file isfile $tmpl]} { - error "The template file '$path' was not found." - } - set fh [open $tmpl r] - set content [read $fh] - catch {close $fh} - return $content - } - - } # # Provide a simple HTML renderer. For now, we make our life simple @@ -1718,7 +1776,6 @@ :forward event=parse %self {% subst {parse@${:current_comment_line_type}}} :method event=next {line} { set next_section [[${:block_parser} processed_section] next_comment_section] - puts stderr "NEXT [${:block_parser} processed_section] [$next_section], [[current] info mixin]" :on_exit $line ${:block_parser} rewind @@ -1728,29 +1785,10 @@ :on_enter $line } - - set :markup_map(sub) { - "{{{" "\[:code \{" - "}}}" "\}\]" - "{{" "\[:link " - "}}" "\]" - } - - set :markup_map(unescape) { - "\\{" "{" - "\\}" "}" - "\\#" "#" - } - - :method map {line set} { - set line [string map [[::nsf::current class] eval [list set :markup_map($set)]] $line] - } - + # realise the sub-state (a variant of METHOD-FOR-STATES) and their # specific event handling :method parse@tag {line} { - set line [:map $line sub] - set line [:map $line unescape] set line [split [string trimleft $line]] set tag [lindex $line 0] if {[:info callable methods -application $tag] eq ""} { @@ -1764,23 +1802,6 @@ } :method parse@text {line} { - - if {![info exists :is_code_block]} { - set :is_code_block 0 - } - - if {[regsub -- {^\s*(\{\{\{)\s*$} $line "\[:code -inline false \{" line] || \ - (${:is_code_block} && [regsub -- {^\s*(\}\}\})\s*$} $line "\}\]" line])} { - set :is_code_block [expr {!${:is_code_block}}] - append line \n - } elseif {${:is_code_block}} { - set line [:map $line unescape] - append line \n - } else { - set line [:map $line sub] - set line [:map $line unescape] - set line [string trimleft $line] - } #puts stderr "ADDLINE :@doc add $line end" :@doc add $line end } Index: library/nx/nx.tcl =================================================================== diff -u -rdbddbce63d4a499de52ff07fdc63c02017960c79 -r5f765b6d8713f416a443cc2367c3a47903cc2f83 --- library/nx/nx.tcl (.../nx.tcl) (revision dbddbce63d4a499de52ff07fdc63c02017960c79) +++ library/nx/nx.tcl (.../nx.tcl) (revision 5f765b6d8713f416a443cc2367c3a47903cc2f83) @@ -103,7 +103,8 @@ # }}} # # @param name The designated identifier on the class or the object to be created. - # @param args Arguments to be passed down to the object creation procedure used to initialize the object. + # @param args arguments to be passed down to the object creation + # procedure used to initialize the object. # @return The name of the created, fully initialized object. # @method ::nx::Class#dealloc Index: tests/doc.tcl =================================================================== diff -u -rcabb7fe9c303839d53970b59262f9ae416aef2eb -r5f765b6d8713f416a443cc2367c3a47903cc2f83 --- tests/doc.tcl (.../doc.tcl) (revision cabb7fe9c303839d53970b59262f9ae416aef2eb) +++ tests/doc.tcl (.../doc.tcl) (revision 5f765b6d8713f416a443cc2367c3a47903cc2f83) @@ -312,7 +312,7 @@ ? [list ::nsf::is $entity object] 1 ? [list $entity info is type ::nx::doc::@object] 1 ? [list $entity @author] "stefan.sobernig@wu.ac.at gustaf.neumann@wu-wien.ac.at"; - ? [list $entity text] "some more text and another line for the description"; + ? [list $entity as_text] "some more text and another line for the description"; set block { {@command ::c} @@ -325,7 +325,7 @@ puts stderr ENTITY=$entity ? [list ::nsf::is $entity object] 1 ? [list $entity info is type ::nx::doc::@command] 1 - ? [list $entity text] "some text on the command"; + ? [list $entity as_text] "some text on the command"; ? [list $entity @see] "::o"; set block { @@ -339,10 +339,10 @@ set entity [CommentBlockParser process $block] ? [list ::nsf::is $entity object] 1 ? [list $entity info is type ::nx::doc::@class] 1 - ? [list $entity text] "some text on the class entity"; + ? [list $entity as_text] "some text on the class entity"; ? [list llength [$entity @param]] 1 ? [list [$entity @param] info is type ::nx::doc::@param] 1 - ? [list [$entity @param] text] "Here, we check whether we can get a valid description block for text spanning multiple lines" + ? [list [$entity @param] as_text] "Here, we check whether we can get a valid description block for text spanning multiple lines" # # basic test for in-situ documentation (initcmd block) @@ -381,7 +381,7 @@ set entity [@class id ::Foo] ? [list ::nsf::is $entity object] 1 ? [list $entity info is type ::nx::doc::@class] 1 - ? [list $entity text] "The class Foo defines the behaviour for all Foo objects"; + ? [list $entity as_text] "The class Foo defines the behaviour for all Foo objects"; ? [list $entity @author] "gustaf.neumann@wu-wien.ac.at ssoberni@wu.ac.at" # TODO: Fix the [@param id] programming scheme to allow (a) for # entities to be passed and the (b) documented structures @@ -395,13 +395,13 @@ ? [list [@class id ::Foo] @method] $entity ? [list ::nsf::is $entity object] 1 ? [list $entity info is type ::nx::doc::@method] 1 - ? [list $entity text] "This describes the foo method"; + ? [list $entity as_text] "This describes the foo method"; foreach p [$entity @param] expected { "Provides a first value" "Provides a second value" } { - ? [list expr [list [$p text] eq $expected]] 1; + ? [list expr [list [$p as_text] eq $expected]] 1; } @@ -479,7 +479,7 @@ set entity [@class id ::Bar] ? [list $i eval [list ::nsf::is $entity object]] 1 ? [list $i eval [list $entity info is type ::nx::doc::@class]] 1 - ? [list $i eval [list $entity text]] "The class Bar defines the behaviour for all Bar objects"; + ? [list $i eval [list $entity as_text]] "The class Bar defines the behaviour for all Bar objects"; ? [list $i eval [list $entity @author]] "gustaf.neumann@wu-wien.ac.at ssoberni@wu.ac.at" # TODO: Fix the [@param id] programming scheme to allow (a) for @@ -494,26 +494,26 @@ ? [list $i eval [list [@class id ::Bar] @method]] $entity ? [list $i eval [list ::nsf::is $entity object]] 1 ? [list $i eval [list $entity info is type ::nx::doc::@method]] 1 - ? [list $i eval [list $entity text]] "This describes the foo method in the method body"; + ? [list $i eval [list $entity as_text]] "This describes the foo method in the method body"; foreach p [$i eval [list $entity @param]] expected { "Provides a first value (refined)" "Provides a second value" } { - ? [list expr [list [$i eval [list $p text]] eq $expected]] 1; + ? [list expr [list [$i eval [list $p as_text]] eq $expected]] 1; } set entity [@method id ::Bar object foo] ? [list $i eval [list [@class id ::Bar] @object-method]] $entity ? [list $i eval [list ::nsf::is $entity object]] 1 ? [list $i eval [list $entity info is type ::nx::doc::@method]] 1 - ? [list $i eval [list $entity text]] "This describes the per-object foo method in the method body"; + ? [list $i eval [list $entity as_text]] "This describes the per-object foo method in the method body"; foreach p [$i eval [list $entity @param]] expected { "Provides a first value" "Provides a second value (refined)" "Provides a third value (first time)" } { - ? [list expr [list [$i eval [list $p text]] eq $expected]] 1; + ? [list expr [list [$i eval [list $p as_text]] eq $expected]] 1; } interp delete $i @@ -569,7 +569,7 @@ doc process -noeval true generic/predefined.tcl ::nx::doc::make doc \ - -renderer ::nx::doc::TemplateData \ + -renderer ::nx::doc::NxDocTemplateData \ -outdir [::nsf::tmpdir] \ -project $project @@ -580,7 +580,7 @@ -namespace "::nx"] doc process -noeval true library/nx/nx.tcl ::nx::doc::make doc \ - -renderer ::nx::doc::TemplateData \ + -renderer ::nx::doc::NxDocTemplateData \ -outdir [::nsf::tmpdir] \ -project $project } @@ -591,21 +591,21 @@ # 2) XOTcl2 documentation project doc process -noeval true library/xotcl/xotcl.tcl ::nx::doc::make doc \ - -renderer ::nx::doc::TemplateData \ + -renderer ::nx::doc::NxDocTemplateData \ -outdir [::nsf::tmpdir] \ -project {name XOTcl2 url http://www.xotcl.org/ version 2.0.0a} # 3) NSL documentation project doc process -noeval true library/nx/nx.tcl ::nx::doc::make doc \ - -renderer ::nx::doc::TemplateData \ + -renderer ::nx::doc::NxDocTemplateData \ -outdir [::nsf::tmpdir] \ -project {name NextScriptingLanguage url http://www.next-scripting.org/ version 1.0.0a} # 4) Next Scripting Libraries # doc process -noeval true ... # ::nx::doc::make doc \ - # -renderer ::nx::doc::TemplateData \ + # -renderer ::nx::doc::NxDocTemplateData \ # -outdir [::nsf::tmpdir] \ # -project {name NextScriptingLibraries url http://www.next-scripting.org/ version 1.0.0a} }