Index: library/lib/nxdoc-assets/@class.html.yuidoc =================================================================== diff -u -r30410351eef652c4e89ab87475b28cead6add6ac -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-assets/@class.html.yuidoc (.../@class.html.yuidoc) (revision 30410351eef652c4e89ab87475b28cead6add6ac) +++ library/lib/nxdoc-assets/@class.html.yuidoc (.../@class.html.yuidoc) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -1,4 +1,4 @@ -[:include filter] +

Class [:print_name -status] @@ -98,9 +98,9 @@ [:for superclass [dict keys $iattrs] { [:!let attrs [dict values [dict get $iattrs $superclass]]]
+ rel="yui:superclass" resource="[$superclass href]">

Inherited Parameters - from [$superclass name]:

Index: library/lib/nxdoc-assets/@object.html.yuidoc =================================================================== diff -u -r30410351eef652c4e89ab87475b28cead6add6ac -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-assets/@object.html.yuidoc (.../@object.html.yuidoc) (revision 30410351eef652c4e89ab87475b28cead6add6ac) +++ library/lib/nxdoc-assets/@object.html.yuidoc (.../@object.html.yuidoc) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -1,4 +1,4 @@ -[:include filter] +

Object [:print_name -status] Index: library/lib/nxdoc-assets/body-chunked.html.yuidoc =================================================================== diff -u -rfa7635cbfe2309b8e6282e2c7925fa2617b061aa -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-assets/body-chunked.html.yuidoc (.../body-chunked.html.yuidoc) (revision fa7635cbfe2309b8e6282e2c7925fa2617b061aa) +++ library/lib/nxdoc-assets/body-chunked.html.yuidoc (.../body-chunked.html.yuidoc) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -1,28 +1,24 @@ -\[\[css:api.css|_|-order 15\]\] -\[\[css:api-next.css|_|-order 16\]\] -\[\[js:api.js\]\] -\[\[js:ac.js\]\] -
-
- [:include leftbar] -
-
- [:? {[info exists include]} { - [:include $include] - } ? {[:info has type ::nx::doc::@project]} { -
- This is the API documentation for the - [:name] project. -

Choose a package, class, object or command name from the list for more information.

-
- [:!let parts $project_entities] - [:include overview] - } - { - - [:include] - }] -
-
+[:!let path [:pathLevels]] +{{set-parameter FolderContextTreeView true}} +{{$path/nxdoc-toc -decoration none -submenu "[:asSubmenu]"}} +\[\[$path/css:api.css|_|-order 15\]\] +\[\[$path/css:api-next.css|_|-order 16\]\] +\[\[$path/js:api.js\]\] +\[\[$path/js:ac.js\]\] +[:? {[info exists include]} { +[:include $include] +} ? {[: -system info has type ::nx::doc::@project]} { +
+ This is the API documentation for the + [:name] project. +

Choose a package, class, object or command name from the list for more information.

+
+[:!let parts $project_entities] +[:include overview] +} - { + +[:include] +}] Index: library/lib/nxdoc-assets/body.html.yuidoc =================================================================== diff -u -rf13893a214c4e18bf6b2b30e0e74a018a10edf0e -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-assets/body.html.yuidoc (.../body.html.yuidoc) (revision f13893a214c4e18bf6b2b30e0e74a018a10edf0e) +++ library/lib/nxdoc-assets/body.html.yuidoc (.../body.html.yuidoc) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -6,9 +6,9 @@
@@ -29,7 +29,7 @@

[$project name]

${:name} - [:? {[:info has type ::nx::doc::@package]} { + [:? {[: -system info has type ::nx::doc::@package]} { [:?var :@version {${:@version}} ] } - { [$project version] @@ -40,7 +40,7 @@ [:include leftbar]

- [:? {[:info has type ::nx::doc::@project]} { + [:? {[: -system info has type ::nx::doc::@project]} {
This is the API documentation for the [:name] project. Index: library/lib/nxdoc-assets/leftbar.html.yuidoc =================================================================== diff -u -r187fbd20a453ae9d73e9b48f88b8d6a8c79685c2 -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-assets/leftbar.html.yuidoc (.../leftbar.html.yuidoc) (revision 187fbd20a453ae9d73e9b48f88b8d6a8c79685c2) +++ library/lib/nxdoc-assets/leftbar.html.yuidoc (.../leftbar.html.yuidoc) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -6,7 +6,7 @@
    [:for inst [dict get $owned_parts $feature] { [:!let css "" ] - [:? {[:info has type [$feature part_class]] && [current] eq $inst} { + [:? {[: -system info has type [$feature part_class]] && [current] eq $inst} { [:!let css "selected" ] }] [:? {[info exists filter_available] && [dict exists $self_owned_parts $feature]} { Index: library/lib/nxdoc-core.tcl =================================================================== diff -u -r7cedf8c74c7f7c1db13880614ac11935045ffe06 -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-core.tcl (.../nxdoc-core.tcl) (revision 7cedf8c74c7f7c1db13880614ac11935045ffe06) +++ library/lib/nxdoc-core.tcl (.../nxdoc-core.tcl) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -103,7 +103,7 @@ set scope [expr {[$mixin scope] eq "object" && \ [$base info is class]?"class":""}] dict lappend :active_mixins $base $mixin - $base {*}$scope mixin add $mixin + $base eval [list : -system {*}$scope mixin add $mixin] } } } @@ -204,7 +204,7 @@ } if {$all} {lappend entity_path $entity [$entity name]} set entity [$entity origin] - if {[$entity info lookup methods -source application @$axis] eq ""} { + if {[$entity eval [list : -system info lookup methods -source application @$axis]] eq ""} { return [list 1 "The tag '$axis' is not supported for the entity type '[namespace tail [$entity info class]]'"] } set entity [$entity @$axis id $value] @@ -358,7 +358,7 @@ } { set id_name $name if {[info exists partof]} { - set id_name ::[join [list [[$partof info class] get_tail_name $partof] $name] ::] + set id_name ::[join [list [[$partof eval {: -system info class}] get_tail_name $partof] $name] ::] } else { set name [:get_fully_qualified_name $name] } @@ -445,6 +445,12 @@ if {[info exists :part_class]} { if {[::nsf::is object $value] && \ [$value info has type ${:part_class}]} { + # + # make sure, the partof relation is set ... whatsoever the + # origin of the current part entity + # + $value partof $domain + $value part_attribute [current] return $value } # puts stderr "NEWWWWWW ${:part_class} new \ @@ -585,17 +591,20 @@ } :public method get_upward_path { - -relative:switch + -relative:switch {-attribute {set :name}} - {-type ::nx::doc::Entity} + {-withContainers:boolean false} } { set path [list] if {!$relative} { lappend path [list [current] [:eval $attribute]] } - - if {[info exists :partof] && [${:partof} info has type $type]} { - set path [concat [${:partof} [current method] -attribute $attribute -type $type] $path] + + if {[info exists :partof] && + ($withContainers || ![${:partof} eval {: -system info has type ::nx::doc::ContainerEntity}])} { + set path [concat [${:partof} [current method] \ + -attribute $attribute \ + -withContainers $withContainers] $path] } return [concat {*}$path] } @@ -630,7 +639,7 @@ if {$pathnames eq ""} { set pathnames $pathspec set pathspec [dict create {*}[$domain get_upward_path \ - -attribute {[:info class] tag}]] + -attribute {[: -system info class] tag}]] set pathspec [dict values $pathspec] } else { set pathspec [split $pathspec .] @@ -652,7 +661,7 @@ :public method origin {} { if {[info exists :@use]} { - if {![::nsf::object::exists ${:@use}] || ![${:@use} info has type [:info class]]} { + if {![::nsf::object::exists ${:@use}] || ![${:@use} info has type [: -system info class]]} { return -code error "Referring to a non-existing doc entity or a doc entity of a different type." } return [${:@use} origin] @@ -700,7 +709,7 @@ StructuredEntity eval { :public method part_attributes {} { - set slots [:info lookup slots] + set slots [: -system info lookup slots] set attrs [list] foreach s $slots { if {![$s info has type ::nx::doc::PartAttribute] || ![$s eval {info exists :part_class}]} continue; @@ -786,7 +795,8 @@ :public method register {containable:object,type=::nx::doc::Entity} { set tag [[$containable info class] tag] - if {[:info lookup methods -source application "@$tag"] ne ""} { + if {[: -system info lookup methods \ + -source application "@$tag"] ne ""} { :@$tag $containable } elseif {[info exists :previous]} { ${:previous} register $containable @@ -809,7 +819,7 @@ :protected method init args { next - :announceAsContainer [:info class] + :announceAsContainer [: -system info class] } } @@ -1212,7 +1222,7 @@ args } { # 1) Are we in a sub-method? - if {[$partof info has type [current]]} { + if {[$partof eval [list : -system info has type [current]]]} { :createOrConfigure [:id [:get_tail_name $partof] "" $name] {*}[current args] } else { next @@ -1230,7 +1240,7 @@ :public method id {domain prop name} { # TODO: ${:part_class} resolves to the local slot # [current], rather than ::nx::doc::@method. Why? - if {[$domain info has type ::nx::doc::@method]} { + if {[$domain eval {: -system info has type ::nx::doc::@method}]} { set id [::nx::doc::@method id [::nx::doc::@method get_tail_name $domain] "" $name] return $id } else { @@ -1261,7 +1271,8 @@ :public method get_combined {what} { set result [list] - if {[info exists :partof] && [${:partof} info has type [current class]]} { + if {[info exists :partof] && + [${:partof} eval [list : -system info has type [current class]]]} { set result [${:partof} get_combined $what] } return [lappend result [:$what]] @@ -1272,7 +1283,7 @@ } :public method get_owning_partof {} { - if {[${:partof} info has type [current class]]} { + if {[${:partof} eval [list : -system info has type [current class]]]} { return [${:partof} [current method]] } else { return ${:partof} @@ -1333,7 +1344,7 @@ # not make it into the object parameters spec, this is fine # for now ... review later. # - if {[${:partof} info has type ::nx::doc::@object]} { + if {[${:partof} eval {: -system info has type ::nx::doc::@object}]} { return "[${:partof} name]::slot::${:name}" } else { next @@ -1400,7 +1411,7 @@ :public method render { {-initscript ""} -theme - {name:substdefault "[::namespace tail [:info class]]"} + {name:substdefault "[::namespace tail [: -system info class]]"} } { :rendered push [current] # Here, we assume the -nonleaf mode being active for {{{[eval]}}}. @@ -1458,7 +1469,8 @@ } set l [list] foreach item $r { - if {![::nsf::object::exists $item] || ![$item info has type ::nx::doc::Entity]} { + if {![::nsf::object::exists $item] || + ![$item eval {: -system info has type ::nx::doc::Entity}]} { lappend l $item } else { if {[[$item origin] eval [list expr $where_clause]]} { @@ -1528,7 +1540,7 @@ :method include { -theme - {name:substdefault "[::namespace tail [:info class]]"} + {name:substdefault "[::namespace tail [: -system info class]]"} } { uplevel 1 [list subst [[:renderer] getTemplate $name \ {*}[expr {[info exists theme]?$theme:""}]]] @@ -2692,7 +2704,7 @@ # -- [current class] revoke - [:info class] containers reset [current] + [: -system info class] containers reset [current] # # TODO: is_validated to later to become a derived/computed # property ... for now, we just need to escape from setting @@ -2756,7 +2768,7 @@ if {$cmdtype ni [list @command @object @class @method]} continue; if {[info exists package] && [dict exists $pkgMap $package]} { set pkgObj [dict get $pkgMap $package] - [:info class] containers push $pkgObj + [: -system info class] containers push $pkgObj unset package } @@ -3035,8 +3047,8 @@ Mixin create [current]::@param -superclass [current]::Entity { :public method init args { - if {[${:partof} info has type ::nx::doc::@method] || \ - [${:partof} info has type ::nx::doc::@command]} { + if {[${:partof} eval {: -system info has type ::nx::doc::@method}] || \ + [${:partof} eval {: -system info has type ::nx::doc::@command}]} { if {${:name} eq "__out__"} { if {[${:partof} pinfo exists bundle returns]} { :pdata [list bundle [list spec [${:partof} pinfo get bundle returns]]] @@ -3059,14 +3071,14 @@ # the parametersyntax. Review later ... # if {${:name} eq "__out__" && \ - [${:partof} info has type ::nx::doc::@command]} return; + [${:partof} eval {: -system info has type ::nx::doc::@command}]} return; # # Here, we escape from any parameter verification for # parameters on forwards & alias, as there is no basis for # comparison! # - if {[${:partof} info has type ::nx::doc::@method] && \ + if {[${:partof} eval {: -system info has type ::nx::doc::@method}] && \ [${:partof} pinfo get bundle type] in [list forward alias]} { dict set :pdata status "" return; Index: library/lib/nxdoc-dc.tcl =================================================================== diff -u -r187fbd20a453ae9d73e9b48f88b8d6a8c79685c2 -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-dc.tcl (.../nxdoc-dc.tcl) (revision 187fbd20a453ae9d73e9b48f88b8d6a8c79685c2) +++ library/lib/nxdoc-dc.tcl (.../nxdoc-dc.tcl) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -535,10 +535,10 @@ :public method assign {domain prop value} { set current_entity [$domain current_entity] set scope [expr {[$current_entity info is class]?"class":""}] - if {[$domain eval [list info exists :$prop]] && [:get $domain $prop] in [$current_entity {*}$scope info mixin classes]} { - $current_entity {*}$scope mixin delete [:get $domain $prop] + if {[$domain eval [list info exists :$prop]] && [:get $domain $prop] in [$current_entity eval [list : -system {*}$scope info mixin classes]]} { + $current_entity eval [list : -system {*}$scope mixin delete [:get $domain $prop]] } - $current_entity {*}$scope mixin add [next [list $domain $prop $value]] + $current_entity eval [list : -system {*}$scope mixin add [next [list $domain $prop $value]]] } } :property current_entity:object @@ -737,7 +737,7 @@ :method parse@tag {line} { lassign [apply [[current class] eval {set :lineproc}] {*}$line] tag line #set line [lassign [apply [[current class] eval {set :lineproc}] {*}$line] tag] - if {[:info lookup methods -source application $tag] eq ""} { + if {[: -system info lookup methods -source application $tag] eq ""} { set msg "The tag '$tag' is not supported for the entity type '[namespace tail [:info class]]" ${:block_parser} cancel INVALIDTAG $msg } @@ -866,7 +866,7 @@ set entity [@$leaf(axis) new -name $leaf(name) {*}$args] } else { - if {[$entity info lookup methods -source application @$leaf(axis)] eq ""} { + if {[$entity eval [list : -system info lookup methods -source application @$leaf(axis)]] eq ""} { ${:block_parser} cancel INVALIDTAG \ "The tag '$leaf(axis)' is not supported for the entity type '[namespace tail [$entity info class]]'" } Index: library/lib/nxdoc-html.tcl =================================================================== diff -u -r30410351eef652c4e89ab87475b28cead6add6ac -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-html.tcl (.../nxdoc-html.tcl) (revision 30410351eef652c4e89ab87475b28cead6add6ac) +++ library/lib/nxdoc-html.tcl (.../nxdoc-html.tcl) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -104,56 +104,11 @@ } return "\[[join $js_array ,\n]\]" } - - :public method navigatable_parts args { - # - # TODO: Should I wrap up delegating calls to the originator - # entity behind a unified interface (a gatekeeper?) - # - set ownedParts [[:origin] owned_parts \ - -where "!\${:@stashed}" \ - -class ::nx::doc::StructuredEntity] - foreach mergeParts $args { - dict for {feature featureInstances} $mergeParts { - if {![dict exists $ownedParts $feature]} { - dict set ownedParts $feature $featureInstances - } else { - set prevInst [lindex [dict get $ownedParts $feature] 1] - lappend prevInst {*}$featureInstances - dict set ownedParts $feature [lsort -unique $prevInst] - } - } - } - - return $ownedParts - } - - :public method navigatable_parts {mergeParts:optional} { - # - # TODO: Should I wrap up delegating calls to the originator - # entity behind a unified interface (a gatekeeper?) - # - set ownedParts [[:origin] owned_parts \ - -where "!\${:@stashed}" \ - -class ::nx::doc::StructuredEntity] - - if {[info exists mergeParts]} { - dict for {feature featureInstances} $ownedParts { - if {![dict exists $mergeParts $feature]} { - dict set mergeParts $feature $featureInstances - } else { - set prevInst [lindex [dict get $mergeParts $feature] 1] - lappend prevInst {*}$featureInstances - dict set mergeParts $feature [lsort -unique $prevInst] - } - } - return $mergeParts - } - - return $ownedParts - } - + # + # no-op + # + :public method navigatable_parts args {;} :method listing {{-inline true} script} { set listing $script @@ -175,7 +130,7 @@ set unresolvable "?" if {[string first @ $tag] != 0} { set m [current method]=$tag - if {[:info lookup methods \ + if {[: -system info lookup methods \ -source application \ -callprotection public $m] eq ""} { return $unresolvable @@ -204,7 +159,7 @@ :public method make_link {source} { set path [dict create {*}[:get_upward_path -attribute {set :name}]] - set tag [[:info class] tag] + set tag [[: -system info class] tag] return [:render_link $tag $source $path] } @@ -225,6 +180,7 @@ # href='[$id href $top_entity]'>[join $pathnames { }]" set iscript [join [list [list set title $pof[join $pathnames .]] \ [list set source_anchor [join $pathnames { }]] \ + [list set srcEntity $source] \ [list set top_entity $top_entity]] \n] :render -initscript $iscript link } @@ -235,18 +191,18 @@ } :method getBase {top_entity:optional} { - set path [dict create {*}[:get_upward_path -attribute {set :name}]] - set originator_top_entity [lindex [dict keys $path] 0] - if {![info exists top_entity] || [dict size $path] == 1} { - set top_entity $originator_top_entity - } - dict unset path $originator_top_entity - set fragment_path [list] - #puts stderr FRAGMENTPATH=$path - dict for {entity name} $path { - lappend fragment_path [$entity filename] - } - return [list $top_entity $fragment_path] + set path [dict create {*}[:get_upward_path -attribute {set :name}]] + puts stderr FRAGMENTPATH([current])=$path + set originator_top_entity [lindex [dict keys $path] 0] + if {![info exists top_entity] || [dict size $path] == 1} { + set top_entity $originator_top_entity + } + dict unset path $originator_top_entity + set fragment_path [list] + dict for {entity name} $path { + lappend fragment_path [$entity filename] + } + return [list $top_entity $fragment_path] } :public method href {-local:switch top_entity:optional} { @@ -265,12 +221,12 @@ if {[info exists :partof]} { return [string trimleft [${:part_attribute} name] @]_${:name} } else { - return [[:info class] tag]_[string trimleft [string map {:: __} ${:name}] "_"] + return [[: -system info class] tag]_[string trimleft [string map {:: __} ${:name}] "_"] } } :public method as_tag_id {} { - set tagclass [:info class] + set tagclass [: -system info class] set tail [$tagclass get_tail_name [current]] set tname [string trimleft [string map {:: _} $tail] "_"] return [$tagclass tag]__$tname @@ -279,27 +235,60 @@ }; # NxDocTemplating::Entity - MixinLayer::Mixin create [current]::@project -superclass [current]::Entity { + + MixinLayer::Mixin create [current]::StructuredEntity -superclass [current]::Entity { + :public method navigatable_parts {mergeParts:optional} { + # + # TODO: Should I wrap up delegating calls to the originator + # entity behind a unified interface (a gatekeeper?) + # + # puts stderr "ENTER owned_parts on [:origin]" + set ownedParts [[:origin] owned_parts \ + -where "!\${:@stashed}" \ + -class ::nx::doc::StructuredEntity] + # puts stderr "LEAVE owned_parts from [:origin]" + + if {[info exists mergeParts]} { + dict for {feature featureInstances} $ownedParts { + if {![dict exists $mergeParts $feature]} { + dict set mergeParts $feature $featureInstances + } else { + set prevInst [lindex [dict get $mergeParts $feature] 1] + lappend prevInst {*}$featureInstances + dict set mergeParts $feature [lsort -unique $prevInst] + } + } + return $mergeParts + } + + return $ownedParts + } + + } + + MixinLayer::Mixin create [current]::@project -superclass [current]::StructuredEntity { :public method filename {} { return "index" } - :public method navigatable_parts args { + :public method navigatable_parts {{-flatten:boolean true} args} { # # TODO: Should I wrap up delegating calls to the originator # entity behind a unified interface (a gatekeeper?) # - set top_level_entities [next [list]] - dict for {feature instances} $top_level_entities { + if {[info exists :topLevelEntities]} { return ${:topLevelEntities} } + set :topLevelEntities [next [list]] + if {!$flatten} {return ${:topLevelEntities}} + dict for {feature instances} ${:topLevelEntities} { if {[$feature name] eq "@package"} { foreach pkg $instances { dict for {pkg_feature pkg_feature_instances} [$pkg navigatable_parts] { - dict lappend top_level_entities $pkg_feature \ + dict lappend :topLevelEntities $pkg_feature \ {*}$pkg_feature_instances } } } } - return $top_level_entities + return ${:topLevelEntities} } } @@ -382,13 +371,14 @@ set iscript [join [list [list set title $title] \ [list set source_anchor $print_name] \ [list set top_entity [current]] \ - [list set cssclass nsfdoc-gloss]] \n] + [list set cssclass nsfdoc-gloss] \ + [list set srcEntity $source]] \n] set res [:render -initscript $iscript link] return $res } }; # NxDocRenderer::@glossary - MixinLayer::Mixin create [current]::@class -superclass [current]::Entity { + MixinLayer::Mixin create [current]::@class -superclass [current]::StructuredEntity { :method inherited {member} { set inherited [dict create] set prj [:current_project] @@ -397,7 +387,7 @@ set exp "expr {\[::nsf::is class ${:name}\]?\[lreverse \[${:name} info heritage\]\]:\"\"}" set ipath [$box do $exp] foreach c [concat $ipath ${:name}] { - set entity [[:info class] id $c] + set entity [[: -system info class] id $c] if {![::nsf::is object $entity]} continue; set origin [$entity origin] if {$origin ni [concat {*}[dict values [$prj navigatable_parts]]]} continue; Index: library/lib/nxdoc-xowiki.tcl =================================================================== diff -u -r187fbd20a453ae9d73e9b48f88b8d6a8c79685c2 -re0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca --- library/lib/nxdoc-xowiki.tcl (.../nxdoc-xowiki.tcl) (revision 187fbd20a453ae9d73e9b48f88b8d6a8c79685c2) +++ library/lib/nxdoc-xowiki.tcl (.../nxdoc-xowiki.tcl) (revision e0f9892926cd7c2c3bf54a1e7d1d945a5c77e7ca) @@ -3,25 +3,344 @@ package require nx::doc::html 1.0 package require nx::serializer -package require base64 -namespace eval ::nx::doc { - Renderer create xowiki -extends [html] { +# +# The necessary xowiki stubs +# + +namespace eval ::xowiki { + # namespace import -force ::nx::* + nx::Class create Page { + :property {lang en} + :property {description ""} + :property {text ""} + :property {nls_language en_US} + :property {mime_type text/html} + :property {title ""} + :property name + :property text + :property page_order # - # yuidoc refinements + # For representing a folder structure # - #$source_anchor + :property parent_id + :property item_id + } + + nx::Class create File -superclass Page + nx::Class create PageTemplate -superclass Page + nx::Class create PlainPage -superclass Page { + :property {mime_type text/plain} + } + nx::Class create Object -superclass PlainPage + + + nx::Class create Form -superclass PageTemplate { + :property {form ""} + :property {form_constraints ""} + } + + nx::Class create FormPage -superclass Page { + :property page_template:integer + :property instance_attributes + } + + + # + # A "folder" prototype form + # + + Form create folder.form \ + -form { + {
    @extra_menu_entries@ @index@ @ParameterPages@
    } text/html + } \ + -form_constraints { + extra_menu_entries:menuentries _nls_language:omit _name:required + } \ + -item_id "1000" \ + -name en:folder.form { + set :__export_reason "implicit_page_template" + } + + # + # A variant of the "toc" includelet, adapted for nxdoc pages ... + # + + Object create includelet.nxdoc-toc \ + -name en:nxdoc-toc \ + -text { + my initialize -parameter { + {-submenu ""} + } + + my proc page_number {page_order remove_levels} { + return "" + } + + my proc href {book_mode name} { + set page [my info parent] + if {![$page exists __including_page]} return + $page instvar package_id __including_page + if {$book_mode} { + set href [$package_id url]#$name + } else { + set href [$package_id pretty_link -parent_id [$__including_page parent_id] $name] + } + return $href + } + + + my proc content {} { + my get_parameters + set page [my info parent] + if {![$page exists __including_page]} return + $page instvar __including_page + set r [$__including_page include [list toc \ + -style none \ + -decoration plain \ + -book_mode 0 \ + -expand_all 1 \ + -ajax 0]] + if {[info command ::__xowiki__MenuBar] ne "" && [llength $submenu]} { + # + # TODO: Right now, there is no way of providing a + # multi-level subtree as the additional_asub_menu helper + # is not applied recursively ... + # + # set items [::xo::OrderedComposite new -destroy_on_cleanup] + # foreach {feat sections} $submenu { + # set pages [::xo::OrderedComposite new -destroy_on_cleanup] + # foreach {name url} $sections { + # set o [xotcl::Object new] + # $o set name $name + # $o set title $name + # $o set page_order 0 + # $pages add $o + # } + # $pages set name $feat + # $pages set title $feat + # $pages set page_order 0 + # $items add $pages + # } + set items [::xo::OrderedComposite new -destroy_on_cleanup] + foreach {feat sections} $submenu { + foreach {name url} $sections { + set o [xotcl::Object new] + $o set name $url + $o set title $name + $o set page_order 0 + $items add $o + } + } + my set book_mode 1 + + ::__xowiki__MenuBar additional_sub_menu -kind folder -pages $items -owner [self] + } + return $r + } + } + + namespace export Page FormPage folder.form +} + +namespace eval ::nx::doc { + # + # In this backend, we aim at generating the following xowiki structure: + # + # `- nx <-- Folder+Page (for all packages) + # `- ::nx::C <-- Folder+Page (for all objects, classes, commands) + # `- ... <-- auto append (from DOM) (e.g., methods, parameters ...) + # `- ... + # `- ... + # `- ... + # `- ::D + # + + namespace import -force ::xowiki::Page ::xowiki::FormPage \ + ::xowiki::folder.form + + nx::Class create EntityFolder -superclass ::xowiki::FormPage { + :property indexPage:object,type=[namespace current]::Page + :public method init {} { + set :item_id [expr {[folder.form item_id] + [llength [[current class] info instances]]}] + set :page_template [folder.form item_id] + set :instance_attributes { + index en:index + extra_menu_entries {} + ParameterPages {} + } + next + } + + :public class method mkFolder {entity} -returns object,type=[current] { + return [:new -name en:[$entity filename] -title [$entity print_name]] + } + + :public method mkFolder {partEntity} -returns object,type=[current] { + set f [[current class] mkFolder $partEntity] + $f parent_id ${:item_id}] + $partEntity folder $f + return $f + } + + :public method mkIndex {entity indexContent contentType} { + set pid [expr {[folder.form item_id] - [llength [[current class] info instances]]}] + set :indexPage [Page new \ + -name "en:index" \ + -item_id $pid \ + -parent_id ${:item_id}] + ${:indexPage} title [$entity name] + ${:indexPage} text [list $indexContent text/html] + } + + :public method serialize {} { + set map [list [current class] [[: -system info class] info superclass]] + set ignore [join [[current class] info slot names] |] + append script [::Serializer deepSerialize -map $map -ignoreVarsRE $ignore [current]] + if {[info exists :indexPage]} { + append script \n [${:indexPage} serialize] + } + return $script + } + } + + + Renderer create xowiki -extends [html] { + + MixinLayer::Mixin create [current]::Entity { + + :public method pathLevels {} { + if {![info exists :levels]} { + lassign [:getEntityPath] basePath + set :levels [expr {[llength $basePath] + 1}] + } + return [join [lrepeat ${:levels} ".."] "/"] + } + + + :method asSubmenu {} { + set features [:navigatable_parts] + set subm [list] + dict for {feature instances} $features { + set tmp [list] + foreach inst $instances { + set d [$inst as_dict [current] $feature] + dict with d { + lappend tmp $name [$inst href -local] + } + } + lappend subm [$feature pretty_plural] $tmp + } + return $subm + } + + :method getEntityPath {} { + set path [dict create {*}[:get_upward_path -withContainers true -attribute {set :name}]] + set prj [:current_project] + set topLevelEntities [concat {*}[dict values [$prj navigatable_parts]]] + set entities [dict keys $path] + + # + # We default to the project entity as base entity ... + # + set baseEntity $prj + foreach e [lreverse $entities] { + if {$e in $topLevelEntities} { + set baseEntity $e; break + } + } + # The "path" contains ... + # 1. ... the path to the base entity (project, package, ...) + # 2. ... the base entity (i.e., the entity which turns into a + # self-contained render unit; a markup page, an xowiki page + # etc.) + # 3. ... the currently rendered entity. If the currently + # rendered and the base entity are not identical, then the + # rendered one turns into a subordinate path (e.g., anchor + # fragments) of the base entitiy. + set baseIdx [lsearch -exact $entities $baseEntity] + set basePath [lrange $entities 0 [expr {$baseIdx - 1}]] + set baseSubs [lrange $entities [expr {$baseIdx + 1}] end] + return [list $basePath $baseEntity $baseSubs] + } + + # + # TODO: The HREF rendering needs to reflect the folder/page + # structure ... + # + :public method href {-local:switch {topEntity:substdefault [current]}} { + lassign [:getEntityPath] basePath baseEntity baseSubs + set fragments [list] + foreach sub $baseSubs { + lappend fragments [$sub filename] + } + set fragments [join $fragments _] + if {$local} { + return $fragments + } else { + set folderPath [list] + lappend basePath $baseEntity + foreach pe $basePath { + set prefix [expr {[$pe eval {info exists :part_attribute}] && \ + [[$pe partof] info has type ::nx::doc::ContainerEntity]?[[$pe part_attribute] pretty_plural]:""}] + lappend folderPath {*}$prefix [$pe filename] + } + # TODO: is the "index" file really necessary, the folder + # default index should actually suffice. Check later ... + lappend folderPath "index" + set href [join [concat [join $folderPath "/"] $fragments] "#"] + # + # TODO: It would be more elegant to render a variant of + # [[..]] blocks which simply return the href ... instead of + # a complete pair. Can we find a more xowiki'sh way? + # + # puts stderr HREF="[[:current_project] url]$href" + return [[:current_project] url]$href + } + } + + :public method filename {} { + set n [string trimleft [string map {:: __} ${:name}] "_"] + if {[info exists :partof]} { + return [string trimleft [${:part_attribute} name] @]_$n + } else { + return [[: -system info class] tag]_$n + } + } + } + + MixinLayer::Mixin create [current]::StructuredEntity \ + -superclass [current]::Entity { + :property folder:object,type=::nx::doc::EntityFolder + + :public method requireFolder {} { + if {![info exists :folder]} { + set folderBuilder [expr {[info exists :partof]?\ + [${:partof} requireFolder]:"::nx::doc::EntityFolder"}] + set :folder [$folderBuilder mkFolder [current]] + } + return ${:folder} + } + } + + MixinLayer::Mixin create [current]::ContainerEntity \ + -superclass [current]::StructuredEntity { + :method asSubmenu {} {;} + } + :addTemplate link yuidoc { - [:! lassign [:getBase {*}[expr {[info exists top_entity]?$top_entity:""}]] base fragment_path] - [:!let basename [expr {[$base info has type ::nx::doc::@glossary]?"en:glossary#[$base name]":"en:[$base filename]#[join $fragment_path _]"}]] + [:!let basename [expr {[: -system info has type ::nx::doc::@glossary]?\ + "[$srcEntity pathLevels]/en:glossary#[:name]":"[:href]"}]] \[\[$basename|$source_anchor\]\] } - :class method render {project entity theme {tmplName ""}} { - - + :class method render { + project + entity:object,type=::nx::doc::StructuredEntity + theme + {tmplName ""}} { set top_level_entities [$project navigatable_parts] set init [subst { set project $project @@ -30,12 +349,21 @@ $entity current_project $project $entity renderer [current] set content [$entity render -initscript $init -theme $theme body-chunked] - set p [::xowiki::Page new -name en:[$entity filename] \ - -title [$entity name] \ - -text [list $content text/html]] - return [$p serialize] + set folder [$entity requireFolder] + $folder mkIndex $entity $content "text/html" + return [$folder serialize] } + + if {[namespace ensemble exists ::binary] && \ + "encode" in [dict keys [namespace ensemble configure ::binary -map]]} { + set fwdTarget [list ::binary encode base64] + } else { + package require base64 + set fwdTarget [list ::base64::encode] + } + :class forward asBase64 {*}$fwdTarget + :class method installAssets {project theme targetDir} { # # render and append single glossary page to the output @@ -57,9 +385,14 @@ -title Glossary \ -text [list $c text/html]] :write [$p serialize] $targetDir + # - # TODO: assets (js, css, img must be wrapped as ::xowiki::Files) + # Dump the "folder" form prototype # + + :write [::xowiki::folder.form serialize] $targetDir + :write [::xowiki::includelet.nxdoc-toc serialize] $targetDir + set assets [glob -directory [file join [findAssetPath] $theme] *] array set mime { @@ -75,29 +408,15 @@ -name file:$filename \ -title $filename \ -mime_type $mime([string trim [file extension $assetPath] "."])] - $f eval [list set :__file_content [::base64::encode [:read -binary $assetPath]]] + $f eval [list set :__file_content [:asBase64 [:read -binary $assetPath]]] :write [$f serialize] $targetDir } } }; # xowiki renderer - # - # The necessary xowiki stubs - # +} - namespace eval ::xowiki { - namespace import -force ::nx::* - Class create Page { - :property {lang en} - :property {description ""} - :property {text ""} - :property {nls_language en_US} - :property {mime_type text/html} - :property {title ""} - :property name - :property text - } - Class create File -superclass Page - } - -} \ No newline at end of file +# +# ./apps/utils/nxdoc -doctitle nx -docurl "http://next-scripting.org/" -docversion 2.0b2 -outdir ./doc -format xowiki -layout many-to-1 -indexfiles library/nx/nxdocIndex.tcl -- "package:nx" +# +#4 \ No newline at end of file