diagrams/diagrams-core — pull request #47 by byorgey (2013-11-13 20:27:42+00:00)
Title: Delayed subtrees

This pull request contains some extra machinery, the original motivation for which was to fix diagrams/diagrams-lib#112, but which I hope may turn out to be more generally useful.

The basic idea is that in addition to having `Prim`s at the leaves of a `QDiagram`, we can now also have a function of type `DownAnnots v -> QDiagram b v m`. That is, a leaf which expands to a `QDiagram` once it knows the final context (including transformations and style) in which it is to be rendered. The prototypical example is an arrow with scale-invariant head and tail, which needs to know the final transformation applied to it before it can figure out exactly how to draw the shaft. (Other possibilities for the future include things like diagrams which do not scale linearly, *e.g.* they scale only up to a certain maximum size and then stop getting bigger.)

The tradeoff is that, as with scale-invariant wrappers, we must come up with an envelope and trace up front---there is no way to delay their generation too (short of a more general solution for constraint solving), since we need them to construct the rest of the `QDiagram`.

There is a bit of trickiness with making sure transformations do not get applied twice. When compiling a `QDiagram` to a raw `DTree` (which now includes expansion of delayed leaves), we mark any expansion points with a special node. Later, when crunching the `DTree` down to an `RTree`, we drop any accumulated transformations upon encountering one of those special nodes. The idea is that the tree underneath that special node, being the expansion of a delayed leaf, must have already taken those transformations into account, so we do not want to apply them again.