Re: marker-pattern syntax

On Tue, Nov 27, 2012 at 8:54 AM, Dirk Schulze <dschulze@adobe.com> wrote:
> Tab, Cameron and I had a discussion about the syntax of 'marker', 'marker-pattern' and 'marker-segment' on IRC yesterday[1].
>
> Tabs proposal is the following:
>
>         marker-pattern: [ [ segment | path ] <distance>? <marker-instance> [ <distance> <marker-instance>? ]* ]#

Actually, that grammar is no longer quite right, based on some of the
tweaks we made to my proposal as the chatroom discussion progressed.
Here's an up-to-date version, formatted for readability:

marker-pattern: [
    [ segment | path ]
    <distance>?
    [
      <marker-instance> |
      <marker-instance> <distance> [ <marker-instance>? <distance> ]*
    ]
  ]#

Now, the first distance is the offset.  It is followed by either a
single marker instance, or a list of (marker-instance, distance)
pairs.  If the former, it paints a single marker at the offset, and
stops.  If the latter, it cycles through the list, painting the marker
then advancing the distance, until the path ends.  (Pairs after the
first may omit their marker-instance, which implies that they should
reuse the last non-omitted one in the list.)  The "path" and "segment"
keywords are as Dirk describes.  This constitutes one "marker track",
and you may provide multiple independent marker tracks
comma-separated.

> The first <distance> would be an optional offset of the marker-pattern (similar to the offset on 'stroke-dasharray').
>
> This would combine marker-pattern and marker-segment and is easy to integrate into the current marker syntax (which is underspecified in SVG 1.1).

In particular, the 'marker' syntax would just become:

marker: <url>{0,3} <'marker-pattern'>

The required "segment" or "path" keyword at the start of
'marker-pattern' would disambiguate.  (Without it, a single "url()" is
a valid 'marker-pattern' value, and thus is ambiguous in the
shorthand.)

> It allow the same syntax for marker-segments as for marker-patterns. The behavior is similar, with some exceptions: For segment, he marker repeat starts on every segment again; relative values are resolved according to the segment length, instead of the path length.
>
> I don't really care about the new keywords and would also be fine to not make 'marker' a shorthand at all and keep 'marker-pattern' and 'marker-segment' separate.
>
> Here some examples and my understanding of the syntax(- is the stroke; # is marker m1, O is marker m2):
>
>         marker-pattern: path url(#m1) 20px;
>         #--#--#--#….
>
>         marker-pattern: path 10px url(#m1) 20px;
>         -#--#--#--#….
>
>         marker-pattern: path 10px url(#m1) 20px 50px;
>         -#--#-----#--#-----#--#….
>
>         marker-pattern: path 10px url(#m1) 20px url(#m2) 50px;
>         -#--#-----O--#-----O--#….
>
>         marker-pattern: path 10px url(#m1) 20px url(#m2) 50px 10px;
>         -#--#-----O-O--#-----O-O--#….

These last two aren't right.  They should be, respectively:

-#--O-----#--O-----#--O---...

-#--O-----O-#--O-----O-#--O---...

The point is that you should be able to just read across the
declaration, drawing symbols and moving distances as they show up.  In
other words, the first one means "starting at a 10px offset, draw #m1,
move 20px, draw #m2, move 50px, etc.".  This is basically a simplified
turtle syntax.  ^_^

> It would also be possible to draw patterns with a specific paint order, which will cause overlapping markers:
>
>         marker-pattern: path 10px url(#m1) 20px, url(#m2) 30px;
>         -#--#--#--#--#--#...
>         O---O---O---O---O…
> m2 would always be drawn on top of m1 (or the other way around, this is up to the specification).

In other words, assuming that later tracks paint on top of earlier
ones, this would render as:

O#--O--#O-#-O#--O...

> Special case, no repeat:
>
>         marker-pattern: path 50px url(#m1);
>         -----#----------------…..
>
>         marker-pattern: path 50px url(#m1), 60px url(#m2);
>         -----#O---------------…..
>
> The syntax and behavior for segment is the same, just that it starts again on every segment.

We could potentially do some fanciness to simplify the common case
that marker-segment is trying to address, too, and make it so that an
omitted offset defaults to "50%" in "segment" mode, rather than the
"0" of "path" mode.  Dunno if that's worthwhile, but it does mean that
we're simply replacing "marker-segment: url()" with "marker-pattern:
segment url()", rather than "marker-pattern: segment 50% url()".  (In
addition to being more verbose, it's not immediately clear what the
difference is between that last one and "marker-pattern: segment url()
50%;", which actually draws *three* markers, at the beginning, middle,
and end of each segment.  Shortening the default case might make this
easier to get right.)  However, defaults changing based on other parts
of the declaration can also be confusing on their own, so I dunno.

> I would like to know if we can agree on the general idea?

+1.

~TJ

Received on Tuesday, 27 November 2012 18:57:05 UTC