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 @@
[$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 {
+ {
} 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
@@ -29,7 +29,7 @@