On Monday, January 6, 2014 3:05:57 PM UTC-6, Edward K. Ream wrote:
> [There remains one last complication, which I have been working on all
> day, namely properly creating all organizer nodes, especially nested
> organizer nodes. Clearly, this is doable: the @organizers tree contains
> all necessary data.
>
> Doable, but very tricky. The problem is that the @organizer: nodes
> contain full unl's of child nodes, but those unl's are invalid until we
> create the organizer nodes, which is what we are trying to do!
>
I believe I see the way forward: create an OrganizerInfo class to
encapsulate various details about each organizer node.
There are at least two new distinctions to be handled:
1. The "raw" unl, which is the unl of the imported node, before the node is
moved to any organizer node. This is the unl stripped of all references to
organizer nodes. Here is the relevant code::
def drop_unl_tail(self,unl):
'''Drop the last part of the unl.'''
return '-->'.join(unl.split('-->')[:-1])
def drop_all_organizers_in_unl(self,organizer_unls,unl):
'''Drop all organizer unl's in unl, recreating the imported url.'''
def key(s):
return s.count('-->')
for s in reversed(sorted(organizer_unls,key=key)):
if unl.startswith(s):
s2 = self.drop_unl_tail(s)
unl = s2 + unl[len(s):]
return unl
2. The **source node** of an organizer node. This is the imported node
that:
a) will become the parent of the organizer node and
b) presently contains all the nodes that will become children of the
organizer node.
Computing the source unl is similar to computing the raw unl, but the
computation drops the tail of the unl only until a non-organizer part is
seen. Probably something like this (untested!):
def source_unl(self,organizer_unls,unl):
'''Return the source_unl of an organizer unl.'''
def key(s):
return s.count('-->')
assert unl in organizer_unls
for s in reversed(sorted(organizer_unls,key=key)):
if unl.startswith(s):
s2 = self.drop_unl_tail(s)
unl = s2 + unl[len(s):]
else: break
return unl
There is also an ever-present complication: moving nodes into an organizer
node has the potential to invalidate previously-computed positions. The
present version of vc.create_organizer_nodes_helper handles this by in
three steps:
- Create the organizer node at the last child of the (source) node
- Demote demoting children in reverse. (They become children of the
organizer node).
- Move the organizer node to the n'th child of the source node.
(n previously computed as the childIndex of the first demoted node).
However, this is not a complete solution to the problem, because nested
organizer nodes may (and usually will) have the same source nodes. I plan
to handle this complication as follows:
- A prepass will create all organizer nodes in a safe place, as children of
a temporary node inserted as the last top-level node.
- Another pass will demote all organized nodes into the proper organizer
node.
- A final pass will move all organizer nodes into *previously computed*
final positions, presumably in reverse outline order. This pass will also
remove the temporary node.
Finally, create_organizer_nodes_helper, the code that actually assigns
nodes to organizer nodes, must handle the potential nesting of organizer
nodes. The general rules:
- Nodes must be assigned to an organizer node from the first node
appearing in the organizer node to the last node appearing in the organizer
node. In other words, extra nodes must be assigned to the organizer node
that is presently accumulating nodes.
- However, if, while accumulating nodes for an organizer node, we see a
node assigned to another (more deeply nested) organizer node, we must start
accumulating nodes for that more deeply nested node.
As a result, create_organizer_nodes_helper is likely to be a recursion on
the length of the unls of all organizer nodes having a particular node as
its source.
Clearly, this is a complex process. However, the new programming freedom
created by the OrganizerInfo instances, and the new clarity created by the
distinctions discussed above promise to solve the puzzle in a *relatively*
straightforward fashion. Furthermore, substantial unit tests are already
in place (they fail at present) that will convincingly demonstrate when the
full solution is at hand.
Maybe today.
Edward
--
You received this message because you are subscribed to the Google Groups
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/groups/opt_out.