-
Notifications
You must be signed in to change notification settings - Fork 2
support drawing commands in quadwriter
#7
Comments
https://github.com/mbutterick/quad/issues/35#issuecomment-501707731
|
https://github.com/mbutterick/quad/issues/35#issuecomment-501733559
|
I’m starting to work on this quad drawing idea. Though rather than a dialect separate from
Quads with a Of course, nothing would stop you from making a That’s fine for shapes and paths. Text gets more complicated, however, because though it’s easy enough to draw text one slug at a time:
... nobody really wants to work with text this way, because
My question to you is — what would be the most natural notation for expressing these ideas (for instance, as you would want to express them in |
The most natural thing would be able to describe a box, with sizing info in addition to placement. The box would also, ideally, either inherit text formatting from the page (font sizing, line heights, justification) or specify its own. The text would then wrap to fit the box. (Maybe a miniature page is a good way to think of it?) As to overflows (by which I suppose we just mean vertical overflows) it would be nice to have the option to either clip off anything that would have been drawn below the bottom of the box, or to let the box expand vertically to fit its contents, or to preserve the box’s size but allow vertical overflow. (There wouldn’t be any difference between the last two except when, e.g., setting a box’s background or border, in which case the difference is visually obvious.) Perhaps eventually you’d be able to arbitrarily chain particular boxes together so that text overflowing past the bottom of one box would flow into the top of the next. |
If quadwriter is going to have SVG-like primitives for vector drawing operations, this kind of brings me back around to my earlier request for having a I’m not wedded to I note that you can render a |
I was thinking of this again when I saw @spdegabrielle post this metapict example the other day. Aside from my own uses for quadwriter/draw ( |
I agree.
That sounds doable except for “expand vertically”, which requires more thought (this would send
That is, in essence, what happens now with the main text flow, though I know what you mean.
I’m wary of making the drawing operations too Racket-centric, inasmuch as the whole idea of Q-expressions is to have an API that is addressable by any external tool (not merely Racket). (See also.) It seems wiser to just allow SVGs to be embedded in PDF. |
After an unforeseen delay I’m returning to this issue. I’m still thinking that supporting freeform drawing from within |
This makes sense, you could give the headers/footers an absolute position that would always be outside the margins of the main content. For header/footer elements, it would be very useful to be able specify the x-coordinate of So on a letter-size page with, say, a 1" outside margin and 0.5" inner margin, you could center a footer under the text block something like this: (q ((draw "text")
(name "footer")
(font-italic "true")
(center-x "true")
(x-offset "-288")
(x-relative-to "spine")
(y "720")
(text "Centered Hello at bottom center")) |
I see what you mean, though I’m learning to be leery of splitting up an attribute like How far could we get by allowing small computations in the value of the attribute? So instead of: (q ((draw "text")
(name "footer")
(font-italic "true")
(center-x "true")
(x-offset "-288")
(x-relative-to "spine")
(y "720")
(text "Centered Hello at bottom center")) We might have: (q ((draw "text")
(name "footer")
(font-italic "true")
(x "page-margin-inner - 288")
(width "page-width - page-margin-inner - page-margin-outer")
(y "720")
(line-align "center")
(text "Centered Hello at bottom center")) |
I’m just realizing, a problem with both of these proposals is that they don’t fully describe a solution to the alternating-page layout problem, which is what I’m trying to address. For example,
Yes I see. I agree your notation is an improvement in this regard, and it’s easier on the eyes as well. Also, though: you could just require that most of these calculations be handled by whatever layer is generating the q-expression. All I care about at the moment is that the draw-quad have enough intelligence to position itself correctly when it matters if it lands on a recto or verso page, which is something you can’t know in advance. Note that my example was attempting to describe how you’d automatically center a draw-quad whose width depends on its contents. But I can see how it would be simpler and better to require the width attribute, and just specify that it be wide enough to handle the biggest thing you might put there. |
Perhaps the (q ((draw "text")
(font-italic "true")
(x "288 from spine")
(width "72")
(y "720")
(line-align "center")
(text "Page 123 of 400")) On a recto page, the resulting x coord would simply be 288. On a verso page, 288 (and I guess, the quad’s |
My idea so far is to handle alternating pages by specifying a So we might handle the problem like so: '(q ((font-italic "true")
(width "72")
(y "720")
(line-align "center")
(text "Page 123 of 400"))
(q ((draw "text")
(page-repeat "left")
(x "page-margin-outer")))
(q ((draw "text")
(page-repeat "right")
(x "page-margin-inner"))) The surrounding quad defines the common attributes (italic, width, y position, centered, etc.) And then the two drawing quads inherit these attributes, but change the (Of course I’m ignoring how the text string knows it’s page |
Yes, that seems much more straightforward. The specific example you gave, though, makes me squint a bit, for other reasons. The surrounding quad has text content and an absolute y-position, but does not have the “draw” attribute? Is a quad then considered to be kind of a ghostly thing that does not take up space on the page unless it has certain attributes/contents? Maybe this is just another thing I haven’t grokked about quads before now. Also, a value containing |
Yes, by analogy to the '(group ((font-italic "true")
(width "72")
(y "720")
(line-align "center")
(text "Page 123 of 400"))
(text
(page-repeat "left")
(x "page-margin-outer")))
(text
(page-repeat "right")
(x "page-margin-inner"))) So far, I’ve avoided attaching any semantics to the tag (so
I suppose it can be both, depending on whether you’re starting at 0. In general I agree with your view that it should be easy to align drawing objects to obvious anchors within the page. Though I’d like to avoid the LaTeX approach of creating a raft of global variables. Moreover, as you say, the layer generating the Q-expression could do all these calculations just as easily. So there is a balance to be struck about who does certain housekeeping. Something that only Quad can do would be, say, centering a line of text, because Quad has access to text measurement, and the other tool does not. |
Since so many formatting operations depend on the resolved locations of certain elements, I’m starting to wonder whether we ought to have some kind of query language to find certain quads in the finished layout. For instance if you wanted the first line of the current page, you could say
Or the 42nd line in the document as a whole:
This could also be adapted for the
We could also extend it to be able to query certain geometric properties, for instance “the y coordinate of the northwest corner of the last line in the first column on this page”:
This seems like a strange thing to want. But the point is that with a query system, there is a coherent way of discovering interesting geometric features on the page. |
(Of course, not a new idea — XML has XPath, HTML has CSS selectors, etc.) |
This may be an uninformed comment—I just noticed a few days ago how much progress you'd made with Allowing "small" expressions in the values of attributes strikes me as sign that you've created an embedded DSL. Just this example, I see a language for attribute values that includes integers, strings, booleans, enumerations (e.g. It didn't occur to me until I thought about the addition of expressions, but my next thought was that many of those things are already present: in particular, the rich variety of datatypes, rather than just strings. I guess at root I'm wondering why you chose to define q-expressions as a subset of x-expressions. I work with a fair amount of XML, and the fact that the only datatypes are strings and elements is one of my least favorite parts. |
To reduce the biggest barrier to adoption. Q-expressions are a stand-in for any data serialization format, all of which can be made to behave in a roughly XML-ish manner. Quad doesn’t foreclose the possibility of using Racket as a richer environment for building Quad layouts. But if that’s the price of admission, no one will use Quad. Whereas if 80% of Quad is available through the API of Q-expressions — which can be generated by any external tool you like, with Quad then serving as a renderer — then Quad will be a lot more useful to a lot more people. That said, I’d like to create as few embedded DSLs as possible. For instance, other things being equal, I’d prefer to avoid supporting computations, because they open the door to mischief and annoyance. By comparison, query strings are relatively contained & benign. |
I’ve just pushed an update that adds drawing quads ( Right now one shortcoming is that if you query for a |
Also, though I’m not claiming Quad’s anchor-attachment model solves all layout problems, it’s already there at the low level, so at the high level, I think it makes more sense to lean into it than to mint some different abstraction. For instance, let’s suppose you wanted to center a text string at the bottom of the page as a footer. Rather than measuring widths and margins and computing, you could just do something like this:
IOW, the natural consequence of the south-to-north joinery is that the drawing quad will be centered horizontally beneath the lower edge of the page. Similarly, to align the drawing quad under the lower left corner, you could change |
No description provided.
The text was updated successfully, but these errors were encountered: