;ò )äHEc@sLdklZdkTdfd„ƒYZd„Zd„Zd„d„ZdS( (s nested_scopes(s*sOutlinecBsptZdZhZhZgZd„Zd„Zd„Zd„Z d„Z d„Z d„Z d„Z d „Zd „Zd „Zd „Zd d„Zd„Zd„Zhd„Zgdd„Zdd„Zdd„Zdd„Zd„Zd„Zd„Zd d„Zd d„Zd„Zd„Z d„Z!e"d„Z#d „Z$d!„Z%e"d"„Z&e"e"d#„Z'RS($s0 I represent and answer questions about a multi-root, multi-parent hierarchy of objects, usually strings, efficiently. This is based on Ken Manheimer's WikiNesting enhancement. For the moment, an Outline has _parentmap = {'Root':[],'Child':['Root'],'GrandChild':['Child'],'Single':[]} _childmap = {'Root':['Child'],'Child':['GrandChild'],'GrandChild':[],'Single':[]} _nesting = [['Root',['Child','GrandChild']],'Single'] A nesting represents outline nodes as follows: Leaves: the string name of the page Nodes with children: a list beginning with the parent node's name Nodes with omitted children (for brevity): list with one string. _childmap and _nesting are derived from _parentmap. Outlines and nestings should perhaps be the same thing. cCs |iSdS(N(sselfs _parentmap(sself((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys parentmapscCs ||_dS(N(s parentmapsselfs _parentmap(sselfs parentmap((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys setParentmapscCs |iSdS(N(sselfs _childmap(sself((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pyschildmapscCs ||_dS(N(schildmapsselfs _childmap(sselfschildmap((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys setChildmapscCs |iSdS(N(sselfs_nesting(sself((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysnestingscCs ||_dS(N(snestingsselfs_nesting(sselfsnesting((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys setNestingscCs$|iƒiƒ}|iƒ|SdS(s"Return a sorted list of all nodes.N(sselfs parentmapskeyssnodesssort(sselfsnodes((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysnodes s cCst|iƒƒSdS(N(slensselfsnodes(sself((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys nodeCount%scCs||iƒjSdS(N(snodesselfsnodes(sselfsnode((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pyshasNode&scCst|iƒƒSdS(s<Return a flattened version of the outline, preserving order.N(sflattensselfsnesting(sself((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysflat'scst‡d†ˆiƒƒSdS(s'Return a sorted list of the root nodes.csˆi|ƒ S(N(sselfsparentssx(sx(sself(s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys,sN(sfiltersselfsnodes(sself((sselfs7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysroots*scst‡d†ˆiƒƒSdS(s'Return a sorted list of the leaf nodes.csˆi|ƒ S(N(sselfschildrensx(sx(sself(s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys/sN(sfiltersselfsnodes(sself((sselfs7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysleaves-sicsU|iƒ}|iƒ}|o h‰n~|iƒph‰xgˆiƒD]X}||j o ˆ|=qJx6ˆ|D])}||j oˆ|i|ƒququWqJWxq|D]i}x`|i |ƒD]O}ˆi |ƒ o|gˆ|LsN(sselfsnodesschildmaps oldchildmapsresetskeysspscsremovesparentsshas_keysappendsfiltersls setChildmap(sselfsresetscs oldchildmapslspschildmapsnodes((schildmaps7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysupdateChildmap0s4     cCs |i|i|iƒƒƒdS(s+Regenerate nesting from childmap and roots.N(sselfs setNestings offspringsroots(sself((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys updateNestingOscCs|iƒ|iƒdS(s)Regenerate everything from the parentmap.N(sselfsupdateChildmaps updateNesting(sself((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysupdateRs cCs|i|ƒ|iƒdS(N(sselfs setParentmaps parentmapsupdate(sselfs parentmap((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys__init__Vs icCs=|iƒ}|||<|i|ƒ|o|iƒndS(sŠ Add node to the outline, under the specified parents if any. If node is already present, it will be reparented. N(sselfs parentmapsparentssnodes setParentmapsupdate(sselfsnodesparentssupdates parentmap((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysaddYs    cCsrx6|i|ƒD]%}|i||i|ƒddƒqW|iƒ}||=|i|ƒ|o|iƒndS(s/ Remove node from the outline. supdateiN( sselfschildrensnodescsreparentsparentss parentmaps setParentmapsupdate(sselfsnodesupdatescs parentmap((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysdeletecs#  c s|iƒ‰|iˆƒ}ˆiˆƒo ˆˆ=n|ˆ|}sN(sselfs parentmapsparentssnodeshas_keysnewnodesfilterskeysscsremovesappends setParentmapschildmapspsindexs setChildmapsupdate( sselfsnodesnewnodesupdatescschildmaps parentmapspsparents((snodes parentmaps7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysreplacems&       # cCs[|iƒ}x(|i|ƒD]}||i|ƒqW|i|ƒ|i|||ƒdS(sE Change node's parents to newparents in the outline. N( sselfschildmapsparentssnodespsremoves setChildmapsadds newparentssupdate(sselfsnodes newparentssupdateschildmapsp((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysreparentŠs  cCst|iƒ}||}|i|ƒ}||||df\||d<||<|||<|i|ƒ|iƒdS(sY Moves child one place to the left among node's children (in _childmap). iN( sselfschildmapsnodeschildrensindexschildsis setChildmaps updateNesting(sselfsnodeschildschildmapsischildren((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysreorder”s  *  cCs'|iƒ}|o |dSntSdS(s4 Get the first node in the outline. iN(sselfsflatslistsNone(sselfslist((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysfirst£s   cCs'|iƒ}|o |dSntSdS(s3 Get the last node in the outline. iÿÿÿÿN(sselfsflatslistsNone(sselfslist((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pyslastªs   cCsn|iƒ}||joM|i|ƒ}|t|ƒdjo||dSqf|o |dSqfntSdS(s3 Get the next node in the outline. iiN( sselfsflatslistsnodesindexsislenswrapsNone(sselfsnodeswrapsislist((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysnext±s  cCsd|iƒ}||joC|i|ƒ}|djo||dSq\|o |dSq\ntSdS(s7 Get the previous node in the outline. iiiÿÿÿÿN(sselfsflatslistsnodesindexsiswrapsNone(sselfsnodeswrapsislist((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysprevious»s   c Cs9h}h}h} h|t<} xÁ| o¹| }h} x¦|iƒD]˜}|i |ƒoqDqDt||<|i |ƒ}|oQxX|D]B}| i |ƒo| |i |ƒn|g| |q>t||<|i |ƒ}|ox&|D]}t| |t||WqWt||<|iƒ}|i h} g} x0|D](}| it||| |iƒƒƒqÝW| SdS(sS Return a nesting representing the ancestors and children of node. N(s ancestorsstopssnodesNonestodosdoingskeyssnshas_keysselfsparentsspssortsdidsgotstsappendsdescend_ancestorsschildmap( sselfsnodes ancestorssdoingstopssnspsparentsstsgotsdidstodo((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysancestorsAndChildrens6     &cCs+| otSn|iƒi|gƒSdS(sN Return a nesting/list representing node's immediate parents. N(snodesNonesselfs parentmapsget(sselfsnode((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysparents$scCs3|iƒi|tƒ}|o |dSntSdS(s: Return the first parent of node, if any. iN(sselfs parentmapsgetsnodesNonesparents(sselfsnodesparents((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys firstParent/s  cCs=|i|ƒ}|i|ƒ}|i|ƒ|iƒ|SdS(s¹ Return a nesting/list representing node's siblings. Ie, any other children of node's first parent. Any siblings by the other parents are not included. N(sselfs firstParentsnodesparentschildrenssibssremovessort(sselfsnodessibssparent((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pyssiblings6s   cCsA|i|ƒo|iƒ|Sn| o|iƒSngSdS(s Return a nesting/list representing node's immediate children. If node is None or [], return the roots. N(sselfshasNodesnodeschildmapsroots(sselfsnode((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pyschildrenBs c Csû|tjo h}ng}xÓ|D]Ë}|i|ƒ}t||<|iƒi|ƒo |dj o{|iƒ|}|oS|g}| o1|i |i |d|o|dd|ƒƒn|i|ƒqï|i|ƒq$|i|ƒq$W|SdS(sj Return a nesting representing all descendants of all specified nodes. nodes is a list of nodes; these will be included in the nesting. did is used only for recursion. If depth is specified, descendendants beyond that depth will be ignored. XXX this is better done in the view layer, remove it. isdepthisdidN(sdidsNonesgotsnodessnshas_keys been_theresselfschildmapsdepthschildrenssubgotsextends offspringsappend( sselfsnodessdidsdepthssubgotsns been_theresgotschildren((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys offspringKs(   $ ((s__name__s __module__s__doc__s _parentmaps _childmaps_nestings parentmaps setParentmapschildmaps setChildmapsnestings setNestingsnodess nodeCountshasNodesflatsrootssleavessupdateChildmaps updateNestingsupdates__init__saddsdeletesreplacesreparentsreordersfirstslastsnextspreviouss ancestorssancestorsAndSiblingssancestorsAndChildrensNonesparentss firstParentssiblingsschildrens offspring(((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysOutlinesJ                      ! "   cCsóg}xÈ|i|ƒo||pgD]¥}|i|ƒ o|i|ƒq(|i|ƒo||pgoN|i|ƒo|i|gƒqÍt||<|it ||||ƒƒq(|i|ƒq(W|i ƒ|i d|ƒ|SdS(s? Create nesting of ancestors leading to page. page is the name of the subject page. ancestors is a mapping whose keys are pages that are ancestors of page children is a mapping whose keys are pages children, and the values are the children's parents. Do not repeat ones we already did. iN( sgotschildrenshas_keyspagescs ancestorssappendsdidsNonesdescend_ancestorsssortsinsert(spages ancestorssdidschildrenscsgot((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysdescend_ancestorsns ""   cCsbg}xQ|D]I}t|ƒttfjo|itt|ƒƒƒq |i |ƒq W|SdS(s3 Flatten a recursive list/tuple structure. N( sflatLists recursiveListsistypesListTypes TupleTypesextendsflattenslistsappend(s recursiveListsflatListsi((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pysflattenscCs9t|ƒtgƒjo|gpt|d„|gƒS(NcCs||||ƒS(N(sasFsb(sasbsF((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys—s(stypesLsreducesF(sLsF((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys—scCs |||ƒS(N(sfsl(slsf((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys—sN(s __future__s nested_scopesstypessOutlinesdescend_ancestorssflattensflatten2(sdescend_ancestorssflatten2sOutlines nested_scopessflatten((s7/mnt/gmirror/ports/www/zope-zwiki/work/ZWiki/Outline.pys?s ÿj