<?xml version="1.0" encoding="utf-8"?><article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0-subset Balisage-1.5"><title>Graceful Diagramming with SVG plus AVTs</title>
    <info>
    <confgroup>
      <conftitle>Balisage: The Markup Conference 2026</conftitle>
      <confdates>August 3-7, 2026</confdates>
   </confgroup>
        <abstract>
            <para>SVG is a mature XML vocabulary for vector graphics, but it has little parametric
                structure and lacks semantic binding between connectors and the objects they
                connect. Drawings produced in SVG are often hard to post-process, maintain, or
                reason about. This paper introduces MVG (Meta Vector Graphics), an extension layer
                over SVG that addresses these isues and can be implemented dynamically or via
                preprocessing into plain SVG 1.0.</para>
            <para>MVG adds general parameter passing via an XSLT-compatible Attribute Value Template
                syntax, at two conformance levels: <emphasis role="ital">heiti</emphasis>-conformant
                processors perform simple named-parameter substitution — nearly trivial to implement
                — while <emphasis role="ital">kenning</emphasis>-conformant processors support full
                XPath expression evaluation at the same syntactic hook. A port model provides named
                attachment points on shapes, enabling connectors and labels to bind semantically
                rather than to coordinates. MVG also adds shape primitives that SVG would otherwise
                represent opaquely. Together these additions allow users to work at a level of
                abstraction closer to their own conceptual models, with benefits for authoring,
                editing, and downstream processing. Python code implementing MVG as a preprocessor
                is provided.</para>
        </abstract>
        <author>
            <personname>
                <firstname>Steven</firstname>
                <othername>J.</othername>
                <surname>DeRose</surname>
            </personname>
            <personblurb>
                <para>Steve DeRose has been working with electronic document and hypertext systems
                    since 1979. He holds degrees in Computer Science and Linguistics and a Ph.D. in
                    Computational Linguistics from Brown University.</para>
                <para>He co-founded Electronic Book Technologies in 1989 to build the first SGML
                    browser and retrieval system, <quote>DynaText,</quote> and has been deeply
                    involved in document standards including XML, TEI, HyTime, HTML 4, XPath,
                    XPointer, EAD, Open eBook, OSIS, and others. He has served as adjunct faculty at
                    Brown and Calvin Universities and has written many papers, two books, and more
                    than fifteen patents. Most recently he has been working as a consultant in text
                    analytics.</para>
            </personblurb>
            <affiliation>
                <jobtitle>Consultant</jobtitle>
                <orgname/>
            </affiliation>
            <email>sderose@acm.org</email>
        </author>
<legalnotice><para>Copyright 2026, Steven J. DeRose.  This work is licensed under a Creative Commons Attribution-Share-alike 3.0 unported license.  See [http://creativecommons.org/licenses/by-sa/3.0/] for more information.</para></legalnotice>
        <keywordset role="author">
            <keyword>SVG</keyword>
            <keyword>XPath</keyword>
            <keyword>XSLT</keyword>
            <keyword>Descriptive Markup</keyword>
            <keyword>Vector graphics</keyword>
        </keywordset>
    </info>

<section><title>1. Introduction: Three Pain Points</title>
<para>SVG [<xref linkend="SVG11"/>] is a well-established and reliable XML schema for drawing. It
            differs from many drawing tools in providing very few shapes, mainly &lt;rectangle&gt;,
            &lt;circle&gt;, and &lt;ellipse&gt; plus generic tools such as &lt;polyline&gt;, &lt;polygon&gt;,
            and &lt;path&gt;. Any other shapes must be constructed from these.</para>
<para>For customization and structure it offers a few tools to define <quote>macro</quote> objects,
            which are used via &lt;use&gt; with <quote>#</quote> plus their ID on @href:</para>
<orderedlist>
    <listitem><para>&lt;g&gt; (for <quote>group</quote>) is rendered where defined. It is useful for re-using objects
                    (via &lt;use&gt;) rather than repeating them entirely.</para></listitem>
    <listitem><para>&lt;symbol&gt; is a more <quote>pure</quote> definition. It is only rendered when referenced. It
                    also imposes its own local co-ordinate space (with clipping to that <emphasis role="ital">viewbox</emphasis>).<footnote>
                        <para>Some browsers have implemented the SVG 2 proposal [<xref linkend="Bell18"/>] to add <emphasis role="ital">refX</emphasis> and
                                <emphasis role="ital">refY</emphasis> to &lt;symbol&gt; (from
                            &lt;marker&gt;).</para>
                    </footnote></para></listitem>
    <listitem><para>&lt;marker&gt; is very similar to &lt;symbol&gt; but adds the option of auto-rotation to the current
                    direction of a &lt;path&gt;, and the notion of a <emphasis role="ital">refX</emphasis>/<emphasis role="ital">refY</emphasis> point to be
                    considered the origin when placed. These are especially useful for arrowheads,
                    so their direction and precise placement are appropriate to the line they are
                    attached to.</para></listitem>
</orderedlist>
<para>Co-ordinates can generally be expressed as percentages of the viewbox height and width. For example, this defines a rectangle with a horizontal bisecting line:</para>
<programlisting xml:space="preserve">
&lt;symbol id="bisected_box" viewBox="0 0 100 200"&gt;
    &lt;rect x="0" y="0" width="100" height="200"/&gt;
    &lt;line x1="0%" y1="50%" x2="100%" y2="50%"/&gt;
&lt;/symbol&gt;
</programlisting>
<para>This can be instantiated via &lt;use&gt;, which may also set <emphasis role="ital">x</emphasis>,
                <emphasis role="ital">y</emphasis>, <emphasis role="ital">height</emphasis>, and
                <emphasis role="ital">width</emphasis>.</para>
<para>This paper introduces <quote>MVG</quote> (short for <quote>Meta Vector Graphics</quote>), a
            layer on top of SVG that tries to address three main pain points related to
            re-use:</para>
<orderedlist>
    <listitem><para>The lack of a general way for &lt;use&gt; to pass values to a referenced object to modify its
                    treatment. This notion adds a lot of power, specifically to make objects
                    declarative rather than procedural.</para></listitem>
    <listitem><para>The lack of a way to attach things (such as ends of lines) to SVG objects rather than
                    co-ordinates.</para></listitem>
    <listitem><para>The lack of some shapes (common in drawing apps) that are not easy to construct.</para></listitem>
</orderedlist>
<section><title>1.1 The reuse/parameterization problem</title>
<para>SVG can draw anything with enough paths (or even a single &lt;path&gt; element, raising and
                lowering the pen as needed). The most salient barrier to creating novel objects and
                expressing them as such, is the lack of a way to pass in values on each use, that
                modify that use.</para>
<para>&lt;use&gt; only allows passing a very small set of predefined properties:</para>
<itemizedlist>
    <listitem><para><emphasis role="ital">x</emphasis>, <emphasis role="ital">y</emphasis>, <emphasis role="ital">width</emphasis>, and <emphasis role="ital">height</emphasis>, without
                        which re-use would be of little use. <emphasis role="ital">transform</emphasis>, which is important for resizing, rotating, etc.
                        And <emphasis role="ital">href</emphasis>.</para></listitem>
    <listitem><para>Presentational attributes (<emphasis role="ital">fill</emphasis>, <emphasis role="ital">stroke</emphasis>, <emphasis role="ital">opacity</emphasis>, etc.) can
                        be <emphasis role="ital">inherited</emphasis> from the calling context, but
                        not <emphasis role="ital">passed in</emphasis> (which is not at all the same
                        thing).</para></listitem>
</itemizedlist>
<para>Such values are known as <quote>parameters</quote>, and are ubiquitous in programming, formal
                logic, math, markup languages, and elsewhere. They greatly reduce space and
                complexity. SVG uses parameters heavily for its built-in constructs; users just
                can't have any for themselves. Consider drawing the unit octagon in SVG:</para>
<programlisting xml:space="preserve">
&lt;polygon points="0.9239,0.3827 0.3827,0.9239 -0.3827,0.9239 -0.9239,0.3827
    -0.9239,-0.3827 -0.3827,-0.9239 0.3827,-0.9239 0.9239,-0.3827" /&gt;
</programlisting>
<para>This is very general: any figure at all can be drawn. However, humans have concepts and terms
                for many more specific shapes (and coin new ones regularly). Humans also associate
                many shapes closely with meanings. Regular polygons are the bread and butter of
                drawing; yet to get them in SVG involves calculating and repeating all those
                coordinates.</para>
<para>Most users would have to look up how to get from <quote>octagon, radius 1</quote> to the set
                of points just shown, and would not readily recognize the points as being a unit octagon.<footnote>
                    <para>Is the reader certain that is even an octagon? It has 8 points and only 3
                        distinct magnitudes; but so would a rectangle traced twice.</para>
                </footnote></para>
<para><emphasis role="ital">For developers</emphasis>, the verbose representation is very slightly easier to implement:</para>
<programlisting xml:space="preserve">
def polygon_from_points(points: list[tuple[float, float]]) -&gt; None:
    moveto(points[0])
    for pt in points[1:]:
        lineto(pt)
    lineto(points[0])
</programlisting>
<para>versus this for regular polygons:</para>
<programlisting xml:space="preserve">
def regular_polygon(cx: float, cy: float, r: float, n: int) -&gt; None:
    offset = math.radians(90 / n)
    moveto(cx + r * math.cos(offset),
           cy + r * math.sin(offset))
    for k in range(1, n + 1):
        lineto(cx + r * math.cos(2 * math.pi * k / n + offset),
               cy + r * math.sin(2 * math.pi * k / n + offset))
</programlisting>
<para>The difference is minor for someone writing graphics code, and they must write similar code
                anyway — it just goes elsewhere. Having <emphasis role="ital">regular_polygon</emphasis> also saves on creating and parsing a long string of
                points, and fits basic principles of software engineering such as <quote>Don't
                    repeat yourself</quote>, as well as being more compact and less
                error-prone.</para>
<para><emphasis role="ital">For power users</emphasis> such as someone writing transforms over the
                SVG, porting data, or looking at the actual values for any reason, the gain is vast.
                With just points it takes real work even to identify all the octagons, especially
                given floating-point number issuess. Just grouping objects into meaningful types is
                a big win [<xref linkend="DeRo20"/>].</para>
<para>Many drawing programs retain shape types internally, but don't exported that data. Inkscape
                makes heavy use of custom options in a separate namespace, which is similar to our
                approach below.</para>
</section>
<section><title>1.2 The connection problem</title>
<para>The first problem I consider is that SVG lacks a notion of connecting things to other things
                per se (cf [<xref linkend="DeRo14"/>]). It does support referring to objects by ID
                for re-use, but this cannot be leveraged for <quote>this line should end at that
                    object</quote>. Actual attachment is implicit, mainly (a) <quote>is drawn by the
                    same &lt;symbol&gt; object</quote>, and (b) <quote>happens to be located
                    nearby</quote>.</para>
<section><title>1.2.1 Connectors</title>
<para>The most obvious need for logical attachment to objects is the <quote>connector</quote>. A
                    connector expresses a semantic relationship between objects. These are
                    ubiquitous in diagrams of all kinds (see definitions in [<xref linkend="DeRo20"/>]), but in SVG no such concept exists. Connectors also differ from most other
                    lines in that they commonly have meaningful direction and terminal
                    arrowheads.</para>
<para>Connectors are trivial for developers to support — you simply retrieve the referenced
                    object's location and use those co-ordinates. However, the distinct problem of
                        <emphasis role="ital">routing</emphasis> the connectors can be harder.
                    Minimal routing solutions are simple: draw a straight line from start to end, or
                    let the user set the route just like they would for &lt;polyline&gt;. But better
                    automatic routing is harder, and a point of competition for
                    implementations.</para>
<para>Omitting the notion of connectors does not ease the routing problem, but adds substantial
                    extra work for users, bloats the data, compromises portability and
                    post-processability, and leads to aesthetic problems.</para>
<itemizedlist>
                    <listitem>
                        <para>Most obviously, if a user moves either box that <emphasis role="ital">seems</emphasis> connected, the line doesn't follow.</para>
                    </listitem>
                    <listitem>
                        <para>Endpoints are imprecise. Snapping helps, but is typically to the
                            background grid, not the target box edge.</para>
                    </listitem>
                    <listitem>
                        <para>Automated processing cannot fix this. Searching for the nearest vertex
                            is a good heuristic, but often fails.</para>
                    </listitem>
                </itemizedlist>
<para>The amount of manual editing work this one omission creates is astonishing, particularly given how ubiquitous connectors are in drawing programs, how conceptually and structurally distinct they are, and how easy they are to implement (at least with basic routing).</para>
</section>
<section><title>1.2.2 Labels</title>
<para>A very similar issue arises because SVG objects do not own labels. A large share of boxes want
                    &lt;text&gt; labels, but in SVG that attachment cannot be readily expressed. One
                    can mebed a &lt;text&gt; object inside another shape, but it doesn't help because
                    one cannot pass specific text in when it is &lt;use&gt;d. </para>
</section>
<section><title>1.2.3 Decorated basic shapes</title>
<para>A third example emerges from the shape inventories of many drawing apps. Many shapes are
                    merely slight modifications of others. For example, <quote>folder</quote> is a
                    rectangle with a small tab added; <quote>page</quote> is a rectangle with a
                    folded corner; flowchart <quote>subprocess</quote> and draw.io's
                        <quote>envelope</quote> are rectangles with extra lines; and so on.</para>
<para>Some cases are achievable with &lt;symbol&gt;, but as before the lack of parameters is limiting.
                    For example, it can't express a &lt;folder&gt; that can position its tab wherever
                    the user wants, or a &lt;decorated-rect&gt; that lets the user choose another shape
                    as decorator.</para>
</section>
<section><title>1.2.4 Walls vs. rooms</title>
<para>A similar case shows up in architecture apps: walls and doors are highly salient user objects,
                    but have an awkward relationship: a wall's two sides belong to different rooms,
                    and some rooms (such as a porch) are not even completely enclosed. Some apps,
                    such as SweetHome 3D [<link xlink:href="https://github.com/ralic/sweethome-3d" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://github.com/ralic/sweethome-3d</link>], use an XML file format
                    and/or can export SVG, but even though walls and rooms may be linked by IDs,
                    they are not inherently related. Worse, they are not even co-located (room edges
                    may be offset by half the walls' thicknesses, with odd consequences).</para>
</section>
<section><title>1.2.5 Ports</title>
<para>At minimum, supporting such connections requires only a way to draw line-like objects whose
                    end locations are given as IDREFs to objects (rather than co-incident
                    co-ordinates). But it is very useful (and common outside SVG) to specify
                        <emphasis role="ital">where</emphasis> on such an object to attach. Most
                    drawing apps provide a notion of <quote>ports</quote> (aka
                        <quote>handles</quote>, <quote>glue points</quote>, or
                        <quote>anchors</quote>), which can be defined on shapes and are attached
                        <emphasis role="ital">to</emphasis>.</para>
<para>Without ports, routing can default. The connection semantic is then intact, but rendering is
                    be ideal. Ports address this.</para>
<para>The user <emphasis role="ital">easily provides</emphasis> port choices when they create line
                    in the first place; apps typically provide <quote>snap to</quote> functionality
                    for this. SVG requires roughly the same work on creation, but adds much work on
                    any edit. The precision problems mentioned earlier may seem minor, but [<xref linkend="Will94"/>] points out that even slight misalignments come across as
                    mistakes in graphic design:</para>
<blockquote>
    <para>A problem with many non-designers' publications is a <emphasis role="ital">subtle</emphasis> lack of alignment [36]</para>
    <para>All these minor misalignments add up to create a visually messy page. [37]</para>
    <para>If your alignments are strong, you can choose to break through the alignment <emphasis role="ital">consciously</emphasis> and it will look intentional. [41]</para>
</blockquote>
</section>
</section>
<section>
            <title>1.3 The creeping generality problem</title>
            <para>Beyond parameters and ports, SVG has no user-accessible constructs for looping or
                calculation (other than expressing co-ordinates as percentages of the current
                viewbox). Rendering some kinds of objects requires multiple operations, such as
                iterating through a <emphasis role="ital">points</emphasis> or <emphasis role="ital">path</emphasis> attribute. Another common need is calculating locations
                relative to the enclosing shape (SVG does have a notion of % of bounding box
                size).</para>
            <para>SVG uses all these concepts inside primitives. Making them user-available,
                however, is a large design task (as the [<xref linkend="Bell18"/>] effort
                discovered), so the SVG limitation is understandable even if unfortunate. Adding
                such features to SVG has been discussed, but never actually finalized.</para>
            <para>SVG does permit embedding Javascript code that operates on the resulting DOM.
                However, it runs at load time rather than separately for (say) each &lt;use&gt; of a
                given &lt;symbol&gt;. XSLT can similarly process SVG code, tokenize points or other
                attributes, and loop or calculate at transform time, writing out more SVG; but it's
                not especially easy. MVG instead proposes a very much smaller extension.</para>
        </section>
<section><title>1.4 Symbol libraries</title>
<para>SVG decided not to include many predefined shapes. Its inventory includes &lt;rect&gt;,
                &lt;circle&gt;, &lt;ellipse&gt;, &lt;line&gt;, &lt;polyline&gt;, &lt;polygon&gt;, and &lt;path&gt;.
                Anything can be drawn somehow, but not always <emphasis role="ital">descriptively</emphasis>.</para>
<para>Nearly all drawing apps have many more shapes than SVG, many of which are familiar and
                intuitive for users. I examined the shape inventories of several drawing apps,,
                primarily graphviz [<xref linkend="GVShapes"/>] and [<xref linkend="Gans93"/>],
                draw.io [<xref linkend="Draw"/>], Inkscape [<xref linkend="Inkscape"/>], and TikZ
                    [<xref linkend="TikZ"/>]. I also considered Canvas, LibreOffice Draw, and
                PowerPoint.</para>
<para>One could never specify all the shapes humans will invent. But some shapes are common, or even
                what [<xref linkend="Pike67"/>] christened <quote>emic</quote>: they are not merely
                a sensory experience, but a more abstract categorial value or symbol.</para>
<para>The good news is that given parameterization and ports only a few shapes enable constructing
                many others. MVG thus defines several new drawing objects, particularly ones that
                require iteration, calculation, or testing conditions. For example, 
                &lt;regular_polygon sides=""&gt; needs to iterate <emphasis role="ital">sides</emphasis> times and do a calculation each time. Others involve
                subdividing a main shape regularly.</para>
<para>The initial MVG implementation is a Python pre-processor that transforms custom elements,
                parameterization, and ports into basic SVG 1.0. It will be placed at
                    <!-- TODO add github URL --><link xlink:href="https://github.com/sderose/mvg" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest"/>,
                and is freely re-usable. It takes only a few hundred lines.</para>
<para>I have sought to choose parameters for consistency across shapes even though shapes can be
                specified in a variety of ways. For example, an ellipse can be specified in any of
                the ways listed below, but I follow the SVG precedent (listed first):</para>
<itemizedlist>
    <listitem><para>Center + two radii (cx, cy, rx, ry) — SVG &lt;ellipse&gt;, TikZ \draw (cx,cy) ellipse (rx and ry), similar to Graphviz.</para></listitem>
    <listitem><para>Bounding box — LibreOffice Draw, PowerPoint/OOXML, draw.io show this, but might not use it internally.</para></listitem>
    <listitem><para>Center + semi-major axis + eccentricity — astronomy/orbital mechanics (Kepler), not drawing tools.</para></listitem>
    <listitem><para>Center + semi-major axis + aspect ratio — TikZ shapes.geometric ellipse uses minimum
                        width/minimum height, which is effectively this. PowerPoint also has
                        something similar.</para></listitem>
    <listitem><para>Parametric angle sweep (cx, cy, rx, ry, start_angle, end_angle) — SVG &lt;path&gt; arc command, Canvas ctx.ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle).</para></listitem>
    <listitem><para>Two foci + point on curve, or two foci + major axis length, or three points on the curve — mathematicians and some CAD or GIS systems (e.g., FreeCAD constraint-based sketcher, PostGIS ST_MinimumBoundingCircle-style fitting).</para></listitem>
    <listitem><para>Center plus conjugate diameters — two vectors from center defining a parallelogram that
                        the ellipse is inscribed in; allows sheared/rotated ellipses without a
                        rotate parameter (Matplotlib's matplotlib.patches.Ellipse?).</para></listitem>
</itemizedlist>
</section>
</section>
<section><title>2 General approach</title>
<para>The overall challenges are adding parameter support, adding ports, and defining the new
            symbols. The layered approach minimizes disturbance to SVG implementations. All the
            extensions use a separate namespace.</para>
<section><title>2.1 Prior work</title>
<para>A lot of conceptual ground has been productively explored by others, some of whom I list here.
                I have tried to build on such concepts, aiming at a <quote>most bang for the least
                    buck</quote> compromise.</para>
<itemizedlist>
    <listitem><para>Mary Holstege's extensive work with XSLT, SVG, and other tools for art [<xref linkend="Hols20"/>] and [<xref linkend="Hols23"/>]</para></listitem>
    <listitem><para>XPath/XSLT/XQuery work such as [<xref linkend="Kay17a"/>] and [<xref linkend="Kay17b"/>]</para></listitem>
    <listitem><para>SVG 2 (a CR) and the SVG Parameters proposal (a WD) [<xref linkend="Sche09a"/>], [<xref linkend="Sche09b"/>], and [<xref linkend="Bell18"/>].</para></listitem>
    <listitem><para>Inkscape and the Sodipodi namespace [<xref linkend="Inkscape"/>]. This architecture is broadly similar, especially in using a secondary namespace to separate extensions, and mapping them (at some level) to regular SVG.</para></listitem>
    <listitem><para>TikZ/PGF [<xref linkend="TikZ"/>]. The node-as-first-class-object also appears prominently here, for example, treating label + bounding box + named anchors as composite unit: <code>\inheritsavedanchors</code>.</para></listitem>
    <listitem><para>GraphML [<xref linkend="GraphML"/>]. This treats <code>&lt;port&gt;</code> as first-class named element, though the position is left to extensions. As noted in [<xref linkend="DeRo20"/>], GraphML's underlying graph-theoretic model is attractive.</para></listitem>
    <listitem><para>Eclipse Layout Kernel [<xref linkend="ELK"/>], [<xref linkend="Domr23"/>]. ELK seems to have the most formally specified port model in the layout literature: side + position + constraint level. I have not gone quite that far.</para></listitem>
</itemizedlist>
</section>
<section><title>2.2 Parameter replacement</title>
<para>Parameterization requires three conceptual parts: declaration, referencing/use, and
                passing.</para>
<para>In XSLT, parameters are declared by full-fledged sub-elements of  &lt;xsl:function&gt;. For
                example:</para>
<programlisting xml:space="preserve">
&lt;xsl:function name="clamp" as="xs:double"&gt;
  &lt;xsl:param name="val"  as="xs:double"/&gt;
  &lt;xsl:param name="hi"   as="xs:double"/&gt;
  &lt;xsl:value-of select="min(($val, $hi)) =&gt; max(0)"/&gt;
&lt;/xsl:function&gt;
</programlisting>
<para>For MVG we want parameters on most or all SVG shapes or shape-like objects, and we don't have
                a &lt;function&gt; element already to hand. For this more limited context, the XSLT
                form seems to me slightly heavy, especially since the existing drawing objects are
                the "functions". A more compact syntax suffices: Parameters are declared merely by
                setting them on the object that is to receive them, with the value there as the
                default. I have shown initial <quote>_</quote> so they cannot collide with SVG
                attributes (of course, such attributes must be added to one's schema for validation
                to work). It is a simple matter for an application to add the attributes to the
                symbol table before interpreting the body:</para>
<programlisting xml:space="preserve">
&lt;symbol id="somegon" _sides="4" _fgcolor="red"&gt;
    ...
&lt;/symbol&gt;
 </programlisting>
            <para>Referring to parameters within the <quote>function</quote> body (e.g., the
                &lt;symbol&gt; element) exactly copies XSLT's Attribute Value Templates (AVT) syntax,
                with curly braces and <quote>$</quote>:</para>
<programlisting xml:space="preserve">
&lt;symbol id="somegon" _sides="4" _fgcolor="red"&gt;
    &lt;polygon sides="{$_sides}" foreground="{$_fgcolor}" /&gt;
&lt;/symbol&gt;
</programlisting>
            <para>For most cases MVG does not need a whole AVT evaluator, but only two very
                constrained specal cases. Thus, MVG developers and users need not implement,
                integrate, or really even understand XPath, XSLT, or AVTs; just those special cases
                (on which see Section 2.2.2).</para>
            <para>Invocation is just using the parameterized drawing element, setting any
                non-default parameters by using attributes in the usual way:</para>
<programlisting xml:space="preserve">
&lt;use href="#somegon" _sides="8" _fgcolor="blue"/&gt;
</programlisting>
<section>
                <title>2.2.1 Automatic parameters</title>
                <para>Given their importance to almost all objects in SVG, the coordinates of the
                    bounding box are likely to be needed often. Therefore MVG defines them to be
                    available as if they were attributes on the object.</para>
                <para>Often, they actually are exactly that: <emphasis role="ital">x</emphasis>,
                        <emphasis role="ital">y</emphasis>, <emphasis role="ital">width</emphasis>,
                    and <emphasis role="ital">height</emphasis> and others are there explicitly, and
                    so naturally available via AVTs. However, they can be given in other ways, or
                    modified. For MVG purposes, we want the resolved values (for example, so objects
                    far away can attach to them). So these attribute names are reserved for that
                    purpose (experience may recommend adding others):</para>
<programlisting xml:space="preserve">
bbLeft   bbRight   bbCenterX
bbTop    bbBottom  bbCenterY
bbWidth  bbHeight
</programlisting>
            </section>
<section><title>2.2.2 Levels of support</title>
<para>The implementation of &lt;use&gt; must interpret the body of the referenced element, replacing
                    AVT expressions in the same way AVTs work in XSLT. This does mean that the final
                    interpretation of the used object must wait until it is used (for example, the
                    implementation can't just interpret it fully when a definition such as
                    &lt;symbol&gt; is first read, and then naively copy the result for each &lt;use&gt;),
                    just as it can't finalize x or y. This may involve some architectural
                    adjustment, but is not in principle difficult.<footnote>
                        <para>For any object that does not have {} in the body, no change is
                            necessary, and those can be cached up front. SVG does not use braces for
                            any of its own syntax.</para>
                    </footnote></para>
<para>To enable simplicity of implementation but also higher functionality, MVG defines two
                    conformance levels. They are named after two devices of Old Norse skaldic
                    poetry:</para>
<para>The first is <emphasis role="ital">heiti</emphasis>-conformant: a <emphasis role="ital">heiti</emphasis> in Norse is a simple synonym substitution — one
                    name for another, no interpretation required. At this level,
                        <code>{$sides}</code> in an attribute value is replaced by the literal
                    string value of the <code>sides</code> parameter. The grammar for references is
                    not the full AVT language, but merely the {$name} and {id($name)/@name}
                    (escaping literal "{" by doublilng it is also necessary):</para>
<programlisting xml:space="preserve">
expr    ::= "{" "$" name "}"
        ::= "{" "id($" name ")/@" name "}"
</programlisting>
<para>The second, optional conformance level is called <emphasis role="ital">kenning</emphasis>. In
                    Norse, a <emphasis role="ital">kenning</emphasis> is a compound poetic
                    expression requiring interpretive calculation, such as <quote>whale-road</quote>
                    for sea.<footnote>
                        <para>The English and proto-Germanic cognates are of course purely
                            accidental.</para>
                    </footnote> At <emphasis role="ital">kenning</emphasis> level, applications
                    support the entire XPath expression language (thus providing arithmetic, string
                    handling, XPath axes, etc.). That greatly increases the power, and is especially
                    valuable for doing arithmetic on co-ordinates. It intergrates in exactly the
                    same way; only the interpreter for the brace-expressions needs to be
                    upgraded.</para>
<para>For <emphasis role="ital">kenning</emphasis>, MVG permits applications to choose the
                    version(s) of XPath to support (likely 2 or 3 at this time). Trigonometric
                    functions are especially important in SVG (see, for example, [<xref linkend="Hols20"/>] and [<xref linkend="Hols23"/>]). They come for free with
                    XPath 3 [<xref linkend="Robi14"/>], or can be provided in XPath 2 [<xref linkend="Berg10"/>] via EXSLT's <quote>math</quote> library, or by other
                    means. The Saxon Java extension mechanism would also work well for this. XPath 1
                        [<xref linkend="Clar16"/>] does not have AVTs. </para>
<para>If starting from scratch, supporting full expressions would involve implementing an XPath
                    engine; but many XPath implementations exist, and many apps involving SVG
                    already have one of those to hand. In that case the extension should be
                    straightforward.</para>
<para>Parameterization of either level must be supported not only for &lt;symbol&gt; and &lt;use&gt;, but
                    for all SVG and MVG elements (that's probably easier anyway; it just goes
                    directly into generic processing).</para>
    <para><emphasis role="ital">text</emphasis> seems to be the only case where {} could occur literally in an SVG attribute, but
                    brace-doubling works for that.</para>
<para>One could consider using CSS <emphasis role="ital">var()</emphasis> and <emphasis role="ital">calc()</emphasis> for some level of parameter support. However, that brings
                    in many other issues, as well as <emphasis role="ital">calc</emphasis> having
                    limited power (see the discussion in [<xref linkend="DeRo18"/>]).</para>
</section>
<section><title>2.2.3 The scaling problem and <code>@scale-lock</code></title>
<para>Some properties should <emphasis role="ital">not</emphasis> scale when the object they are
                    part of scales (perhaps font-size, line-weight, dashed-line segment lengths,
                    etc) . It may prove necessary to offer a scale-lock setting for these, but with
                    parameters it is likely possible to get all the needed effects in other
                    ways.</para>
</section>
</section>
<section><title>2.3 Port and anchor models</title>
<section><title>2.3.1 Port definition</title>
<para>The fundamental requirements for ports include a way to define them when defining a &lt;symbol&gt; with a name and a location; and a way to attach objects (connectors, labels, shape-decorators, etc) to them.</para>
<para>An MVG port name is an XML NAME, with three additional requirements. They:</para>
<itemizedlist>
    <listitem><para>must be unique within each &lt;symbol&gt;, but may be re-used in different ones;</para></listitem>
    <listitem><para>must not contain <quote>.</quote> (more on that below);</para></listitem>
    <listitem><para>must not match the name of any attribute SVG defines (especially for &lt;use&gt;).</para></listitem>
</itemizedlist>
<para>Port definitions look like this:</para>
<programlisting xml:space="preserve">
&lt;symbol id="foo"&gt;
    &lt;port name="top" x="100%" y="0"/&gt;
    &lt;port name="foo-3" x="10" y="25%"/&gt;
    ...usual SVG...
&lt;/symbol&gt;
</programlisting>
<para><emphasis role="ital">x</emphasis> and <emphasis role="ital">y</emphasis> attributes, with
                    co-ordinate values as usual (including possibly with <quote>%</quote>), specify
                    the port's location in the &lt;symbol&gt;'s viewbox. They mayt point outside the
                    viewbox; one might, after all, want to place something adjacent but outside the
                    target object.</para>
<para>This method is not great for shapes like circles or ellipses (quick! tell me the x% and y% for
                    the upper-right of the unit circle). Many drawing apps support compass points
                    for this and other uses (for example, Graphviz, TikZ, and mxGraph/Visio). Some
                    others support numeric angles (for example, TikZ/PGF, though it counts in the
                    opposite direction from SVG). Therefore, MVG also allows <emphasis role="ital">angle</emphasis> as a mutually-exclusive alternative to <emphasis role="ital">x</emphasis> and <emphasis role="ital">y</emphasis>. <emphasis role="ital">angle</emphasis>'s value may be either a reference angle
                    (counting in degrees CW from east), or one of the 8 major compass points (upper
                    case), or CENTER (which is also the default if none of <emphasis role="ital">x</emphasis>, <emphasis role="ital">y</emphasis>, or <emphasis role="ital">angle</emphasis> is provided):</para>
<programlisting xml:space="preserve">
&lt;port name="port2" angle="NE".../&gt;
</programlisting>
<para>For convenience, the 8 compass point abbreviations and CENTER are also predefined to be port
                    names with the same meanings. Users may not re-define them via &lt;port&gt;. Port
                    name ANCHOR also has a special meaning, to be discussed later.<footnote>
                        <para>Note that directions like NE are not defined to be at 315° on the
                            bounding box, but at the corner of it, projected toward the center until
                            hitting non-background such as the shape's visual edge.</para>
                    </footnote></para>
<para>Also allowed is edge segment number plus distance along that edge. MVG currently permits this
                    in this form (segments count from 1 like XPath, and the second token defaults to
                    50% for distance along that segment):</para>
<programlisting xml:space="preserve">
&lt;port name="foo" segment="5 30%" /&gt;
</programlisting>
<para>This is especially valuable for &lt;polygon&gt; and similar. However, this is only meaningful
                    given a normative starting segment. That segment is known for <emphasis role="ital">polyline</emphasis> and <emphasis role="ital">polygon</emphasis>. Curves are construed as having only 1 segment. For shapes
                    that do not have an obvious starting segment, we define the outermost segment
                    passing through Θ = 0 as that segment. If the segment number is out of range for
                    the object, Θ = 0 is used instead.</para>
<para>Note that the precise placement behavior relative to any of these locations is slightly
                    different for labels, ports, and decorators. A port is actually a point, so on a
                    rectangle, specifying NE or a corresponding angle means a connector actually
                    terminates on that corner. However, a label or decorator occupies space with the
                    object it is bound to, and so needs to know which part of it goes right on the
                    port.</para>
<para>This is easily solved. Labels and decorators are themselves objects, and so can define their
                    own ports. As noted earlier a port named ANCHOR is reserved, which is used as
                    the label's or decorator's place to align with the specified port on the target
                    object. ANCHOR can have its location defined like any other port, but it
                    defaults to the center of the bounding box.</para>
</section>
<section><title>2.3.2 Port reference</title>
<para>Reference to ports may be useful in various places, such as:</para>
<itemizedlist>
    <listitem><para>specifying the attachment target for connectors or similar</para></listitem>
    <listitem><para>replacing a point location within &lt;polyline points="..."/&gt; or similar</para></listitem>
    <listitem><para>referring to the port's x or y location in cases where SVG expects those as separate items.</para></listitem>
</itemizedlist>
<para>But there are a few syntactic issues for using port names. Using a port requires also
                    specifying the object (typically via &lt;use&gt;). SVG references typically specify
                        <quote>#</quote> plus an ID value using <emphasis role="ital">href</emphasis>. But where should MVG put the port name?</para>
<orderedlist>
                    <listitem>
                        <para>It could go on an additional attribute, but that seems a bit clumsy
                            and doesn't fit neatly into existing SVG objects or XPath queries (
                            these &lt;polyline&gt; could as well be a new &lt;connector&gt; type):<programlisting xml:space="preserve">
&lt;polyline start="#obj12" start-port="S" end="#obj30" end-port="NE"/&gt;
</programlisting></para>
                    </listitem>
    <listitem><para>It could be added as if it were a second fragment identifier, but that is a bit odd:<programlisting xml:space="preserve">
&lt;polyline start="#obj12#S" end="#obj30#NE"/&gt;
</programlisting></para></listitem>
   <listitem><para>It could be compounded onto the ID so the compound remained an XML NAME, but I think it would be less clear:
<programlisting xml:space="preserve">
&lt;polyline start="#obj12.S" end="#obj30.NE"/&gt;
</programlisting></para></listitem>
</orderedlist>
<para>Considering that such locations could also be quite useful as <emphasis role="ital">points</emphasis>, it seems desirable to keep them as single tokens, and to
                    make a way to refer separately to their actual <emphasis role="ital">x</emphasis> and <emphasis role="ital">y</emphasis> locations
                    (post-resolution). But that means <quote>x</quote> or <quote>y</quote> must also
                    be specified somehow.</para>
<para>In addition, it is highly desirable to have a compact, readable way to refer to port locations
                    in XPath expressions (both in general, and for MVG itself).</para>
<para>Getting at such values is possible, but not pretty in XPath:</para>
<programlisting xml:space="preserve">
id(objId)/port[@name = 'NE']/@x
</programlisting>
<para>However, the entire second step can be eliminated by this defining that a port definition P on
                    an object has the effect of creating attributes on each &lt;use&gt; of the object
                    (implementations may calculate these lazily). The attributes' names and values
                    are:</para>
<orderedlist>
    <listitem><para>P (the same as the port name), whose value is the string of the resolved co-ordinates of the
                            port in that object's viewbox.</para></listitem>
    <listitem><para>P.x (that is, the port name with <quote>.x</quote> appended), whose value is the x coordinate
                            of the port; and</para></listitem>
    <listitem><para>P.y (that is, the port name with <quote>.y</quote> appended), whose value is the y coordinate
                            of the port.</para></listitem>
</orderedlist>
<para>Note that all these names are still valid XML NAMEs. The dots here are why port names are not
                    allowed to contain dots. In XPath, the expression shown above then shortens to
                    this:</para>
<programlisting xml:space="preserve">
id(objId)/@NE.x
</programlisting>
<para>This is just normal XPath given the generated attributes just defined (that is, the XPath
                    implementation doesn't have to know that <quote>.</quote> is special here).
                    Within a &lt;symbol&gt; or similar definition, the ID for a particular &lt;use&gt; of
                    it is not known. This means we need also to add it to the available attributes
                    (as <quote>use_id</quote>).</para>
<para>The same syntax could be embedded within <emphasis role="ital">points</emphasis> or other
                    attributes for implementations that provide no support for more complete XPath
                    expression syntax in {}.</para>
<para>There is some added value in having access to properties of an object more generally,
                    particularly width and height, as well as the handy x+width and y+height, which
                    are the opposite corner of the bounding box (perhaps as <emphasis role="ital">x2</emphasis> and <emphasis role="ital">y2</emphasis>. It requires little
                    effort to support the form above for all SVG elements and attributes (the XPath
                    would just work). Indeed, it would typically take more programming effort to
                        <emphasis role="ital">avoid</emphasis> that. In that case the port-specific
                    usage reduces to the convention that the locations of an object's ports are
                    attributed to the object for convenience.</para>
</section>
<section><title>2.3.3 Connector routing</title>
<para>MVG distinguishes the fact of connection from the routing chosen to render it. Routing
                    algorithms are highly varied, and differ greatly in complexity. Thus, MVG
                    defines names for several general approaches, but does not require apps to
                    implement any but <quote>line</quote> and <quote>polyline</quote>, which have
                    the same behaviors as those SVG elements.</para>
<para>MVG introduces a <emphasis role="ital">routing</emphasis> attribute for those elements, which
                    is a pragmatic hint that renderers may treat as a request for a particular
                    routing method. If an unsupported routing method is requested, apps may simply
                    fall back to <emphasis role="ital">line</emphasis> for lines, and <emphasis role="ital">polyline</emphasis> for polylines.</para>
<para>See [<xref linkend="Wybr06"/>] and [<xref linkend="Tama87"/>] for general information on routing. The defined routing method names in MVG are:</para>
<itemizedlist>
    <listitem><para><emphasis role="ital">direct</emphasis> (straight line from port to port; as noted in [<xref linkend="DeRo20"/>] this may be ugly, but at least expresses the correct connection);</para></listitem>
    <listitem><para><emphasis role="ital">poly</emphasis> (user-specified waypoints)</para></listitem>
    <listitem><para><emphasis role="ital">orthogonal</emphasis> (alternating horizontal and vertical segments, with the first and last segments no colinear with the face(s) adjacent to the respective port) [<xref linkend="Wybr09"/>]</para></listitem>
    <listitem><para><emphasis role="ital">curved</emphasis> (for example, using spline interpolation) [<xref linkend="Dobk97"/>] and [<xref linkend="Frei01"/>]</para></listitem>
    <listitem><para><emphasis role="ital">force-directed</emphasis> this acts as if the connectors contain springs, and minimizes stretching force [<xref linkend="Eade84"/>] and [<xref linkend="Fruc91"/>] Such methods are sometimes integrated with movement of the endpoint shapes</para></listitem>
    <listitem><para><emphasis role="ital">auto</emphasis> (obstacle avoidance, not otherwise specified). [<xref linkend="Dobk97"/>] and [<xref linkend="Dwye09"/>]</para></listitem>
    <listitem><para><emphasis role="ital">bundling</emphasis> some algorithms also combine parts of connectors to reduce crowding [<xref linkend="Holt06"/>]</para></listitem>
</itemizedlist>
<para>Additional types of routing may be supported by implementations, and should be named beginning
                    with <quote>x-</quote>.</para>
<para>MVG also provides a hint to control what happens when connectors cross. Common renderings are
                    (a) do nothing, (b) open a small gap for one, or (c) render a half-circle hop
                    for one. These can be expressed in MVG as shown below, but applications are not
                    required to implement them. If an unsupported value is requested, the attribute
                    is ignored, and SVG's default behavior (essentially <emphasis role="ital">none</emphasis>) applies.</para>
<programlisting xml:space="preserve">
&lt;mvg:connector mvg:crossings="bridge|gap|none"...&gt;
</programlisting>
<para>Connectors, labels, and lines may also have ports,</para>
</section>
</section>
</section>
<section><title>3. Design Principles</title>
<para>MVG provides a few elements in a separate namespace from SVG. All can be implemented fairly
            easily in the sort of environment where SVG is in use, and all can be mapped to vanilla
            SVG 1. I provide a pre-processor implementation that does just that.</para>
<para>MVG's additions should be highly intuitive to users of XML, XSLT, and SVG, because they re-use
            notions that are very well known there. The overall goal is to make MVG more
            descriptive, so users can define shapes and other constructs that correspond better to
            their own conceptual models, and that greatly reduce tedium.</para>
</section>
<section><title>4. Additional Shapes</title>
<para>A review of shape inventories across multiple drawing apps revealed these shapes which are
            difficult to implement merely via SVG &lt;symbol&gt;, even with MVG parameterization added.
            Usually this is because they need iteration or non-trivial conditional logic. An MVG
            implementation should provide them. I provide implementations of them in Python for
            convenience.</para>
<para>The specific criteria for inclusion here are that a shape showed up in at least one of the
            drawing app inventories considered, or greatly eases construction of other shapes; and
            that expressing it in SVG 1.x requires either</para>
<itemizedlist>
    <listitem><para>an unbounded number of elements or coordinates as a function of its parameters — O(n)
                    SVG for O(1) conceptual content, or</para></listitem>
    <listitem><para>a fixed number of coordinates that are opaque encodings of a small parameter set, with the parametric structure lost. The first criterion is the stronger case; the second covers shapes like block arrows where the vertex count is fixed but coordinates are non-recoverable functions of shaft-width, head-width, head-depth, etc.</para></listitem>
</itemizedlist>
        <para>All these elements also allow the transform or rotate attributes common in SVG.</para>
<section><title>4.1 <code>mvg:rpolygon</code> — </title>
<para>This represents a regular polygon by its center, radius, number of sides, and rotation:
                    <code>@cx</code>, <code>@cy</code>, <code>@r</code>, <code>@sides</code>.</para>
</section>
<section><title>4.2 <code>mvg:roundpolygon</code> — </title>
<para>This represents a polygon (not necessarily regular) but with uniform rounded corners. It is
                specified like SVG &lt;polygon&gt;, but adding <code>@corner-r</code> to represent the
                radius for the rounded corners.</para>
</section>
<section><title>4.3 <code>mvg:star</code> —</title>
<para>A star polygon, in which alternating vertices have radii of r-inner and r-outer.
                    <code>@cx</code>, <code>@cy</code>, <code>@n</code>, <code>@r-outer</code>,
                    <code>@r-inner</code>. n should typically be even. Based on Inkscape
                    <code>sodipodi:star</code>.</para>
</section>
<section><title>4.4 <code>mvg:arc</code> — </title>
<para>This is similar to ellipse, but can draw just a portion: a circular or elliptical arc.
                    <code>@cx</code>, <code>@cy</code>, <code>@r</code>, <code>@start-angle</code>,
                    <code>@end-angle</code>. SVG has circle and ellipse but lacks this useful case.
                Drawn clockwise.</para>
</section>
<section><title>4.5 <code>mvg:smoothcurve</code> — </title>
<para>This draws a smooth spkine curve (such as Catmull-Rom) through <code>@points</code> knots.
                User specifies knots only; preprocessor computes Bézier control points. This
                can eliminate many cases where SVG ends up containing of large static coordinate
                dumps being briefer, more perspicuous, and propertly scalable.</para>
</section>
<section><title>4.6 <code>mvg:wave</code> — </title>
<para>This draws basic sine, cosine, and other periodic curves. <code>@x1 @y1 @x2 @y2</code>,
                    <code>@type</code> (sine | square | sawtooth | triangle),
                    <code>@amplitude</code>, <code>@frequency</code>, <code>@phase</code>. x and y
                represent placement of the origin. This covers the <emphasis role="ital">document</emphasis> shape's bottom edge, but is generally useful in technical
                work. Phase is measured in degrees. Phase 0 must be defined for each wave type, for
                example sine rises rightward from (0,0). The conventions I have encountered for the
                others seem to prefer falling from their maximum amplitude.</para>
<para><emphasis role="ital">type</emphasis> permits <quote>x-</quote> prefixed values for extension,
                and such extensions must specify their initial phase state.</para>
</section>
<section><title>4.7 <code>mvg:spiral</code> — </title>
<para>Draw an Archimedean spiral. <code>@cx</code>, <code>@cy</code>, <code>@r-start</code>,
                    <code>@r-end</code>, <code>@turns</code>, <code>@t0</code> (start fraction,
                0–1). Subsumes Inkscape <code>sodipodi:spiral</code>.</para>
</section>
<section><title>4.8 <code>mvg:curly-brace</code> —</title>
<para>This represents the curly braces commonly needed in technical drawing. <code>@x1 @y1 @x2
                    @y2</code> (endpoints), <code>@depth</code> (bow depth),
                    <code>@orientation</code> (left | right). Consists of three Bézier curves
                whose control points are computed from the parameters.</para>
</section>
<section><title>4.9 <code>mvg:tile</code> — </title>
<para>This provides simple iteration across x and/or y. Within a bounding box, repeats a child
                element at regular intervals of  dx and dy. For example:</para>
<programlisting xml:space="preserve">
&lt;mvg:tile x="0" y="0" width="400" height="300"
         dx="50" dy="50"
         nx="8" ny="6"
         odd-row-phase-x="0.5"&gt;
  &lt;mvg:ngon sides="6" r="20" cx="0" cy="0" style="fill:none; stroke:#ccc"/&gt;
&lt;/mvg:tile&gt;
</programlisting>
<para><code>dx</code>/<code>nx</code> and <code>dy</code>/<code>ny</code> are complementary pairs: specify either spacing or count; the other is derived from the bounding box dimension. If both are given, <emphasis role="ital">count</emphasis> takes precedence and <emphasis role="ital">spacing</emphasis> is computed.</para>
<para>Phase attributes <code>@phase-x</code>, <code>@phase-y</code> offset the whole pattern relative to the bounding box. <code>@odd-row-phase-x</code>, <code>@even-row-phase-x</code>, <code>@odd-col-phase-y</code>, <code>@even-col-phase-y</code> do this for alternating rows and columns in units of dx/dy, as needed for brick, hexagonal, and some other layouts). Rows and columns count from 1. All phase attributes default to 0.</para>
<para>Basic grids fall out as a special case: a horizontal line child repeated at <code>dy</code>
                intervals, plus a vertical line child repeated at <code>dx</code> intervals. A minor
                grid can be handled via two nested <code>mvg:tile</code> elements with different
                stroke styles.</para>
</section>
        <section>
            <title>4.10 itransform</title>
            <para><!-- TODO Add definition -->This is somewhat similar to &lt;tile&gt;, but instead of
                simply moving the sub-object across the referencing object's bounding box, it
                repeatedly applies a transform. This enables positioning things across an affine
                path.</para>
        </section>
<section><title>4.11 coil (from TikZ)</title>
<para><!-- TODO Add definition --></para>
</section>
<section><title>4.12 <code>mvg:block-arrow</code> — </title>
<para>This provides an (optionally filled) directional arrow shape. <code>@direction</code> takes
                the same values as the <emphasis role="ital">angle</emphasis> parameter of
                &lt;port&gt;s. <code>@shaft-width</code>, <code>@head-width</code>,
                    <code>@head-depth</code> define basic arrowhead dimension. <code>@tip</code>
                uses the arrowhead types defined below.</para>
</section>
<section><title>4.13 block_arc (from OOXML)</title>
<para><!-- TODO Add definition -->This is basically like arc (see above), but draws the arc twice,
                separated by <code>@shaft-width</code> and centered at the given r.</para>
</section>
<section><title>4.14 Line types</title>
<para>SVG <code>&lt;line&gt;</code> already provides extensive control over stroke rendering. Comparison with multiple drawing apps suggested only a few additions, all expressed as <code>mvg:</code> presentation attributes applicable to any stroked element (shapes, connectors, or standalone lines):</para>
<para><code>@mvg:crossings</code> — controls what happens when connectors cross.<footnote><para>This may be better limited to only <code>&lt;mvg:connector&gt;</code>?</para></footnote>  Three values: <code>none</code> (do nothing, the SVG default), <code>gap</code> (open a small break in the lower connector), and <code>bridge</code> (render a half-circle hop). Implementations are encouraged but not required to implement all three; the interaction with routing choice is noted in §2.3.3.</para>
<para><code>@mvg:stroke-repeat</code> and <code>@mvg:stroke-gap</code> — draws multiple copies of the stroke, to make double, triple, or similar lines. <emphasis role="ital">stroke-gap</emphasis> control blank space between the repetitions. The entire set of strokes is centered where a single stroke would be centered. The result if this is used with dashed lines is not defined.</para>
<para><code>@mvg:corner-radius</code> — generalizes SVG's <code>rx</code>/<code>ry</code> on <code>&lt;rect&gt;</code> to <code>&lt;polygon&gt;</code> and <code>&lt;polyline&gt;</code>, with a single uniform radius (no rx/ry distinction). Deliberately avoids the <code>rx</code>/<code>ry</code> names, which mean something different on <code>&lt;ellipse&gt;</code>.</para>
<para>With these additions, nearly all the line-type capabilities of the surveyed apps are covered.</para>
</section>
<section>
            <title>4.15 Arrowheads</title>
            <para>Drawing apps also commonly provide libraries of arrowheads, which can attach to
                the ends of (at least) lines. My review found high overlap on basic forms, but much
                variation at the edges. A large share of the variations, however, are easily
                constructible with general SVG and MVG constructs.</para>
            <para>MVG defines but does not require, an &lt;mvg:arrowhead&gt; object that works like SVG
                &lt;marker&gt; but has settings that can produce a wide range of arrowheads. Arrowhead
                size is governed by the bounding box and transform on &lt;mvg:arrowhead&gt;, just like
                SVG &lt;marker&gt;.</para>
            <para>The attribute are those of &lt;marker&gt;, plus:</para>
            <itemizedlist>
                <listitem>
                    <para>shape: either <quote>none</quote> (or <quote/>), or one of
                            <quote>triangle</quote>, <quote>vee</quote>, <quote>dot</quote>,
                            <quote>diamond</quote>, <quote>box</quote>, <quote>tee</quote>,
                            <quote>curve</quote>, <quote>crow</quote> (drawn from ER diagrams).
                        Extensions should be prefixed by <quote>x-</quote>. These are the same as in
                        graphviz once you remove affixes such as used in <quote>odiamond</quote>
                        (open diamond). The affixes are covered by the other settings, which also
                        make them slightly more general than in graphviz. <quote>inv</quote> in
                        graphviz means a 180° rotation, so can be done with SVG's ubiquitous
                            <emphasis role="ital">transform</emphasis> or with marker <emphasis role="ital">orient</emphasis>. graphviz <quote>normal</quote> is just
                            <quote>triangle</quote>.</para>
                </listitem>
            </itemizedlist>
            <para>Because Unicode has a huge variety of useful arrows (e.g., U+2190–U+21FF),
                dingbats, and other shapes, MVG defines the convention that if <emphasis role="ital">shape</emphasis> is set to a single Unicode character, that character is used.
                The 0 rotation has the character readable from the perspective on one standing on
                the line leading up to it, and scaled to fill the &lt;marker&gt; viewbox.</para>
            <itemizedlist>
                <listitem>
                    <para>filled: <quote>open</quote>, <quote>halfopen</quote>, or
                            <quote>filled</quote> (the default).</para>
                </listitem>
                <listitem>
                    <para>clipped: <quote>left</quote>, <quote>right</quote>, or <quote>full</quote>
                        (the default)</para>
                </listitem>
            </itemizedlist>
            <para>MVG does not address the fact that graphviz allows stacking a sequence of
                arrowheads onto a line-end.</para>
            <para>Several other arrowhead types I found are addressable by the Unicode-character
                alternative:</para>
            <itemizedlist>
                <listitem>
                    <para>some EE conventions (primarily in Europe?) use slash or backslash-like
                        shapes as arrowheads.</para>
                </listitem>
                <listitem>
                    <para>OOXML has a <emphasis role="ital">bracketArr</emphasis> head, that looks
                        like a square bracket.</para>
                </listitem>
                <listitem>
                    <para>LibreOffice has a wavy or zigzag terminus, for which various tildes
                        (U+0007e, U+FF5E, etc.), wave dash (U+301C), almost equal to (U+2248), or
                        sine wave (U+223F) may suffice.</para>
                </listitem>
                <listitem>
                    <para>TikZ has quite a few more.</para>
                </listitem>
            </itemizedlist>
        </section>
</section>
<section><title>5. Connectables</title>
<section><title>5.1. Connectors</title>
<para>Connectors do not require a new element, but are simply a useful combination of &lt;line&gt; or
                &lt;polyline&gt; with parameterization, ports, and the <emphasis role="ital">routing</emphasis> pragma. For example:</para>
<programlisting xml:space="preserve">
&lt;mvg:line obj1="id1" port1="e"
              obj2="id2" port2="w"
              routing="direct"
              linetype="dashed"
              arrow1="none" arrow2="filled-triangle"&gt;
&lt;/mvg:line&gt;

&lt;text&gt; objects to serve as labels may be attached to a connector
just as they are to other shapes.
</programlisting>
</section>
<section><title>5.2 Labels</title>
<para>SVG &lt;text&gt; objects benefit from parameters and ports, and can simply refer to the object to
                which they attach instead of setting <emphasis role="ital">x</emphasis> and
                    <emphasis role="ital">y</emphasis> position manually. It would instead be
                feasible to express the attachment the other way. However, that would need to apply
                to many (all?) shapes and grouping objects, and would need a way to do either raw
                strings, or objects with more structure such as complex formatting properties or
                multiple &lt;text&gt; parts.</para>
<para>&lt;text&gt; objects in MVG can define ports just like other objects. By default, their
                    <code>ANCHOR</code> port is placed at the <code>ANCHOR</code>  of the referenced
                object (<code>ANCHOR</code> defaults to the center of the relevant bounding
                box).</para>
</section>
<section><title>5.3 Decorators</title>
<para>A <emphasis role="ital">decorator</emphasis> is the MVG term for a shape (perhaps a
                &lt;symbol&gt; or &lt;marker&gt;) attached to a host shape to create a new (sub-)class of
                shape. For example, the commonplace folder shape can be constructed (or construed)
                as a rectangle with an extra rect or round-rect placed somewhere along the
                top.</para>
<para>Given MVG as already described, decorators are simply a concept; no additional elements are
                required. Both shapes can be drawn by an enclosing &lt;symbol&gt; or similar, or one
                can be attached by setting its location using a port or coordinate reference to the
                host shape. The decorator's own <code>ANCHOR</code> port aligns with the host's
                target port, and the decorator inherits the host's coordinate system for rendering
                purposes.</para>
<para>Decorator positioning reuses the port-location grammar of §2.3.1: <code>@attach</code> names the host port; <code>@anchor</code> names the decorator's own contact point (default: <code>anchor</code> port of the decorator, which itself defaults to center). The <code>@scale-lock</code> attribute (§2.2.3) prevents decorators from scaling disproportionately when the host is resized.</para>
<para>No new element type is required. A decorator is any <code>mvg:symbol</code> instance referred to from an <code>@attach</code> attribute on <code>&lt;mvg:use&gt;</code>:</para>
<programlisting xml:space="preserve">
&lt;mvg:use href="#tab" attach="n" anchor="s"
         mvg:width="{$tab-w}" mvg:height="{$tab-h}" /&gt;
</programlisting>
<para>The preprocessor resolves the port coordinates and emits an SVG <code>&lt;use&gt;</code> at the
                computed position.</para>
</section>
</section>
<section><title>6. Conclusions</title>
<para>This work defines and implements MVG, a layer over SVG that provides more declarative,
            user-oriented construction for drawings. Everything in it can be reduced to plain SVG
            (for example, with the provided pre-processor).</para>
<para>It is mainly intended to make it easier, clearer, and more compact to express drawings
            descriptively in cases where that is difficult to do in plain SVG. It provides two
            conformance levels: <emphasis role="ital">heiti</emphasis>-conformant (string
            substitution only — nearly trivial to implement) and <emphasis role="ital">kenning</emphasis>-conformant (full XPath AVT expression evaluation). The <emphasis role="ital">heiti</emphasis> level paves the way for <emphasis role="ital">kenning</emphasis> because the latter merely attaches a better AVT expression
            evaluator in the same context as the trivial one needed for <emphasis role="ital">heiti</emphasis>.</para>
</section>
<bibliography><title>Bibliography</title>
  <bibliomixed xml:id="Bell18" xreflabel="Bell18">Bellamy-Royds, Amelia; Bogdan, Brinza; Lilley, Chris; Schulze, Dirk; Storey, David; and Willigers, Eric. Scalable Vector Graphics (SVG) 2. W3C Candidate Recommendation 04 October 2018. <link xlink:href="https://www.w3.org/TR/SVG2/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/SVG2/</link>
  </bibliomixed>
  <bibliomixed xml:id="Berg10" xreflabel="Berg10">Berglund, Anders; Boag, Scott; Chamberlin, Don; Fernández, Mary F.; Kay, Michael; Robie, Jonathan; and Siméon, Jérôme. XML Path Language (XPath) 2.0 (Second Edition). W3C Recommendation 14 December 2010. <link xlink:href="https://www.w3.org/TR/xpath20/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/xpath20/</link>
  </bibliomixed>
        <bibliomixed xml:id="GraphML" xreflabel="GraphML">Brandes, Ulrik, et al. 2014. <quote>Graph
                Markup Language (GraphML).</quote> In Tamassia (ed.), <emphasis>Handbook of Graph Drawing and Visualization</emphasis>. CRC Press. <link xlink:href="http://cs.brown.edu/people/rtamassi/gdhandbook/chapters/graphml.pdf" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">http://cs.brown.edu/people/rtamassi/gdhandbook/chapters/graphml.pdf</link>
        </bibliomixed>
  <bibliomixed xml:id="Clar16" xreflabel="Clar16">Clark, James and DeRose, Steve. XML Path Language (XPath) Version 1.0. W3C Recommendation 16 November 1999 (Status updated October 2016). <link xlink:href="https://www.w3.org/TR/xpath-10/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/xpath-10/</link>
  </bibliomixed>
        <bibliomixed xml:id="SVG11" xreflabel="SVG11">Dahlström, Erik; Dengler, Patrick; Grasso,
            Anthony; Lilley, Chris; McCormack, Cameron; Schepers, Doug; Watt, Jonathan; Ferraiolo,
            Jon; FUJISAWA, Jun (藤沢 淳); and Jackson, Dean. Scalable Vector
            Graphics (SVG) 1.1 (Second Edition). W3C Recommendation 16 August 2011. <link xlink:href="https://www.w3.org/TR/SVG11/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/SVG11/</link>
        </bibliomixed>
  <bibliomixed xml:id="DeRo14" xreflabel="DeRo14">DeRose, Steven J. “What do we still lack? Or: Prolegomena to any future hypertext system.” Presented at Symposium on HTML5 and XML, Washington, DC, August 4, 2014. In <emphasis>Proceedings of the Symposium on HTML5 and XML</emphasis>. Balisage Series on Markup Technologies, vol. 14 (2014). doi:<biblioid class="doi">10.4242/BalisageVol14.DeRose01</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="DeRo18" xreflabel="DeRo18">DeRose, Steven J. “Dynamic Style: Implementing Hypertext through Embedding Javascript in CSS.” Presented at Balisage: The Markup Conference 2018, Washington, DC, July 31 - August 3, 2018. In <emphasis>Proceedings of Balisage: The Markup Conference 2018</emphasis>. Balisage Series on Markup Technologies, vol. 21 (2018). doi:<biblioid class="doi">10.4242/BalisageVol21.DeRose01</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="DeRo20" xreflabel="DeRo20">DeRose, Steven. “What is a diagram, really?” Presented at Balisage: The Markup Conference 2020, Washington, DC, July 27 - 31, 2020. In <emphasis>Proceedings of Balisage: The Markup Conference 2020</emphasis>. Balisage Series on Markup Technologies, vol. 25 (2020). doi:<biblioid class="doi">10.4242/BalisageVol25.DeRose01</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Dobk97" xreflabel="Dobk97">Dobkin, D.P.; Gansner, E.R.; Koutsofios, E.; and North, S.C. <quote>Implementing a General-Purpose Edge Router.</quote> In DiBattista (ed.), <emphasis>Graph Drawing (GD 1997)</emphasis>, LNCS 1353, pp. 262–271. Springer, 1997.
  doi:<biblioid class="doi">10.1007/3-540-63938-1_68</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Domr23" xreflabel="Domr23">Domrös, Sören; von Hanxleden, Reinhard; Spönemann, Miro; Rüegg, Ulf; and Schulze, Christoph Daniel. The Eclipse Layout Kernel. <link xlink:href="https://arxiv.org/abs/2311.00533" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://arxiv.org/abs/2311.00533</link>. doi:<biblioid class="doi">10.48550/arXiv.2311.00533</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Draw" xreflabel="Draw">JGraph Ltd. draw.io / diagrams.net. <link xlink:href="https://www.drawio.com" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.drawio.com</link>
  </bibliomixed>
  <bibliomixed xml:id="Dwye09" xreflabel="Dwye09">Dwyer, T. and Nachmanson, L. <quote>Fast Edge-Routing for Large Graphs.</quote> In Eppstein &amp; Gansner (eds.), <emphasis>Graph Drawing (GD 2009)</emphasis>, LNCS 5849, pp. 147–158. Springer, 2009.
  doi:<biblioid class="doi">10.1007/978-3-642-11805-0_15</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Eade84" xreflabel="Eade84">Eades, P. <quote>A Heuristic for Graph Drawing.</quote> <emphasis>Congressus Numerantium</emphasis> 42:149–160, 1984.
  </bibliomixed>
  <bibliomixed xml:id="Frei01" xreflabel="Frei01">Freivalds, K. <quote>Curved Edge Routing.</quote> In Freivalds (ed.), <emphasis>Fundamentals of Computation Theory</emphasis> (FCT 2001), LNCS 2138, pp. 126–137. Springer, 2001. 
  doi:<biblioid class="doi">10.1007/3-540-44669-9_14</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Fruc91" xreflabel="Fruc91">Fruchterman, T.M.J. and Reingold, E.M. <quote>Graph Drawing by Force-Directed Placement.</quote> <emphasis>Software: Practice and Experience</emphasis>  21(11):1129–1164, 1991.
  doi:<biblioid class="doi">10.1002/spe.4380211102</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Gans93" xreflabel="Gans93">Gansner, E.R.; Koutsofios, E.; North, S.C.; and Vo, K.-P. <quote>A Technique for Drawing Directed Graphs.</quote> <emphasis>IEEE Transactions on Software Engineering</emphasis> 19(3):214–230, 1993.
  doi:<biblioid class="doi">10.1109/32.221135</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="GVShapes" xreflabel="GVShapes">Graphviz. Node Shapes. <link xlink:href="https://graphviz.org/doc/info/shapes.html" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://graphviz.org/doc/info/shapes.html</link>
  </bibliomixed>
  <bibliomixed xml:id="Hols20" xreflabel="Hols20">Holstege, Mary. “XML for Art: A Case Study.” Presented at Balisage: The Markup Conference 2020, Washington, DC, July 27 - 31, 2020. In <emphasis>Proceedings of Balisage: The Markup Conference 2020</emphasis>. Balisage Series on Markup Technologies, vol. 25 (2020). 
  doi:<biblioid class="doi">10.4242/BalisageVol25.Holstege01</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Hols23" xreflabel="Hols23">Holstege, Mary. “Adventures in Single-Sourcing XQuery and XSLT.” Presented at Balisage: The Markup Conference 2023, Washington, DC, July 31 - August 4, 2023. In <emphasis>Proceedings of Balisage: The Markup Conference 2023</emphasis>. Balisage Series on Markup Technologies, vol. 28 (2023). 
  doi:<biblioid class="doi">10.4242/BalisageVol28.Holstege01</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Holt06" xreflabel="Holt06">Holten, D. <quote>Hierarchical Edge Bundles: Visualization of Adjacency Relations in Hierarchical Data.</quote> <emphasis>IEEE Transactions on Visualization and Computer Graphics</emphasis> 12(5):741–748, 2006. 
  doi:<biblioid class="doi">10.1109/TVCG.2006.147</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Inkscape" xreflabel="Inkscape">Inkscape Project. <link xlink:href="https://inkscape.org" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://inkscape.org</link>
  </bibliomixed>
  <bibliomixed xml:id="Kay17a" xreflabel="Kay17a">Kay, Michael, ed. XSL Transformations (XSLT) Version 3.0. W3C Recommendation, 8 June 2017. <link xlink:href="https://www.w3.org/TR/xslt-30/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/xslt-30/</link>
  </bibliomixed>
  <bibliomixed xml:id="Kay17b" xreflabel="Kay17b">Kay, Michael, ed. XPath and XQuery Functions and Operators 3.1. W3C Recommendation, 21 March 2017. <link xlink:href="https://www.w3.org/TR/xpath-functions-31/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/xpath-functions-31/</link>
  </bibliomixed>
  <bibliomixed xml:id="Pike67" xreflabel="Pike67">Pike, Kenneth L. <emphasis role="ital">Language in Relation to a Unified Theory of the Structure of Human Behavior.</emphasis> 2nd rev. ed. The Hague: Mouton, 1967. (First published in three parts, 1954–1960.)
  </bibliomixed>
  <bibliomixed xml:id="Robi14" xreflabel="Robi14">Robie, Jonathan; Chamberlin, Don; Dyck, Michael; and Snelson, John. XML Path Language (XPath) 3.0. W3C Recommendation 08 April 2014. <link xlink:href="https://www.w3.org/TR/xpath-30/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/xpath-30/</link>
  </bibliomixed>
  <bibliomixed xml:id="Sche09a" xreflabel="Sche09a">Schepers, Doug. SVG Parameters 1.0, Part 1:
            Primer. W3C Working Draft 16 June 2009. <link xlink:href="https://www.w3.org/TR/2009/WD-SVGParamPrimer-20090616/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/2009/WD-SVGParamPrimer-20090616/</link>
        </bibliomixed>
  <bibliomixed xml:id="Sche09b" xreflabel="Sche09b">Schepers, Doug. SVG Parameters 1.0, Part 2: Language. W3C Working Draft 16 June 2009. <link xlink:href="https://www.w3.org/TR/2009/WD-SVGParam-20090616/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://www.w3.org/TR/2009/WD-SVGParam-20090616/</link>
  </bibliomixed>
        <bibliomixed xml:id="ELK" xreflabel="ELK">Schulze, C. Sönke, et al. Eclipse Layout
            Kernel. <link xlink:href="https://eclipse.dev/elk/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://eclipse.dev/elk/</link>
        </bibliomixed>
  <bibliomixed xml:id="Tama87" xreflabel="Tama87">Tamassia, R. <quote>On Embedding a Graph in the Grid with the Minimum Number of Bends.</quote> <emphasis>SIAM Journal on Computing</emphasis> 16(3):421–444, 1987. 
  doi:<biblioid class="doi">10.1137/0216030</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="TikZ" xreflabel="TikZ">Tantau, Till. The TikZ and PGF Packages. Manual for version 3.1.x. <link xlink:href="https://tikz.dev/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">https://tikz.dev/</link>
  </bibliomixed>
  <bibliomixed xml:id="Will94" xreflabel="Will94">Williams, Robin. <emphasis>The Non-Designer's Design Book: Design and Typographic Principles for the Visual Novice</emphasis>. Peachpit Press, 1994. ISBN 978-1-56609-159-4.
  </bibliomixed>
  <bibliomixed xml:id="Wybr06" xreflabel="Wybr06">Wybrow, M.; Marriott, K.; and Stuckey, P.J. <quote>Incremental Connector Routing.</quote> In Healy &amp; Nikolov (eds.), <emphasis>Graph Drawing (GD 2005)</emphasis>, LNCS 3843, pp. 446–457. Springer, 2006. 
  doi:<biblioid class="doi">10.1007/11618058_40</biblioid>
  </bibliomixed>
  <bibliomixed xml:id="Wybr09" xreflabel="Wybr09">Wybrow, M.; Marriott, K.; and Stuckey, P.J. <quote>Orthogonal Connector Routing.</quote> In Eppstein &amp; Gansner (eds.), <emphasis>Graph Drawing (GD 2009)</emphasis>, LNCS 5849, pp. 219–231. Springer, 2009. 
  doi:<biblioid class="doi">10.1007/978-3-642-11805-0_22</biblioid>
  </bibliomixed>
</bibliography>
</article>