Keith Ross Crib Diagrams XML

This documents an XML for defining crib diagrams. Once you've created the xml file, run it through k2s to create an svg file that most browsers can display.

Before we begin, make sure you are familiar with the concept of a crib diagram. It is a way of describing a dance as a series of little pictures or standardized icons. I have made a few extensions in order to describe English Country Dance as well as Scottish.

(I have never gotten around to writing a DTD)

Table of Contents

<krcd>

Example

The <krcd> element.

<krcd>

The root element of these files is always <krcd>.

Attributes
header-leftThis specifies a header to be displayed on the upper left of the crib diagram. It usually contains the dance name, all in upper case.
header-midThis specifies a header to be displayed in the middle of the top row of the crib diagram. Most dances don't use this, but a dance with two names might use this to display its secondary name.
header-rightThis specifies a header to be displayed on the upper right of the crib diagram. It generally specifies the type of music needed for the dance as: 8×32 R.
footer-leftThis specifies a footer to be displayed in on the bottom left of the crib diagram. It usually contains the devisor, the date, and the first publication containing the dance. For old dances it might also contain the interpreter, the date of interpretation, and the name of the publication containing that interpretation. This may also be specified as a node element, for more complicated information.
footer-rightThis specifies a footer to be displayed in on the bottom right of the crib diagram. It usually contains the formation for the dance like: 3C/4C longways.

A <krcd> element may contain one <footer-left> node. This is when you want to put a link into the footer (and so need something more complicated than simple text. You may not have both a <footer-left> element and a footer-left attribute in the same file.

A <krcd> element may contain an arbitary number of <box>, <meanwhile> and <sequence> nodes.

The <footer-left> element.

This replaces the footer-left attribute of the <krcd> element. It contains a set of svg children and may be used to put links (or any arbitrary drawing) into the left footer space.

<footer-left> has no attributes and only svg children

Example

<krcd
    header-left="THE DANCING WIFE"
    header-right="×32 R"
    footer-left="Gary Roodman, 1992, Additional Calculated Figures<"
    footer-right="DM longways" >

Could be replaced by:

<krcd
    header-left="THE DANCING WIFE"
    header-right="×32 R"
    footer-right="DM longways" >
  <footer-left>
    <a href="https://calculatedfigures.com/">
    <text class="footer" x="0" y="0">Gary Roodman</text>
    </a>
    <text class="footer" x="142" y="0">, 1992, Additional Calculated Figures</text>
  </footer-left>

To add a link to Gary Roodman's website.

The <box> element.

The <box> is the way information is expressed to the user. Box elements have two forms, one for simple standard icons, and one the user types in svg code to draw a more complicated picture.

Each box controls a small rectangle on the output canvas and usual describes one figure of the dance in that rectangle.

Attributes
headerThis specifies a header to be displayed on the upper line of the box. If the header does not contain the "|" character then the header will be centered in the box. If it contains one "|", as for example "left|right" the the text to the left of the "|" will be displayed on the left, while the remainder is displayed to the right of the box. If there are two "|" then the three bits of text will be either left-adjusted, centered, or right-adjusted. Etc.
notes-topThis is very similar to a header but uses a different type size.
notes-bottomThis is very similar to notes-top but is placed at the bottom of the box.
notes-bottom2This is very similar to notes-bottom but is placed one line up from the bottom of the box.
strainThis is for English Country Dance and is used to mark the beginning of a new strain of music with this box. It usually has a value like "A1" or "B2".
line-break-afterForce a line break after this box. Usually k2s will pack as many boxes as it can onto one line of the output canvas (with a few constrains), but if the user needs better control this can force a linebreak where the user wants it.
show-start-barsWhen there's a repeat later in the diagram that repeat may specify which bars are to be repeated. This explicitly marks the box with the bar-count for the start of the box.
show-end-barsWhen there's a repeat later in the diagram that repeat may specify which bars are to be repeated. This explicitly marks the box with the bar-count for the end of the box.
barsSpecifies the number of bars needed to perform the figure displayed in the box. This is a required attribute (unless the box is a child of a meanwhile in which case the box borrows this information from its parent).
dividerk2s usually draws a divider after every box, the divider varies depending on if the box ends with the bar-count a multiple of 8 (in which case a solid line is drawn), a multiple of 4 (a dashed line), or a multiple of 2 (a dotted line). If you don't want a divider drawn specify 'divider="false"'.

textMany figures can be expressed with standard icons. For instance "T" means "turn your partner". If you want you can include the svg commands from drawing a "T" inside the box body, or you can just say 'text="T"' the the program will generate those commands.
modifierIn the above example "T" does not fully describe a turn, you also need to know whether to turn them with the right, left, or both hands. This allows you to express that 'text="T" modifier="R"'.
halfIf you want to say something like "half rights and lefts" you express it as 'text="RL" half="true"' But for some things like turn it seems more common to say: 'text="T" modifier="R½"'.

text2If you want to collect a sequence of simple figures into one box you can use 'text2', 'modifier2', and 'half2' to define a second figure.

text3If you want to collect a sequence of simple figures into one box you can use 'text3', 'modifier3', and 'half3' to define a third figure.

text4If you want to collect a sequence of simple figures into one box you can use 'text4', 'modifier4', and 'half4' to define a fourth figure.

If a box does not have a "text" attribute then in must have svg children which define what is to be drawn in the box. k2s will figure out the width and height of what the svg elements draw and then center those elements with in the rectangle given over for drawing the box. Each line of the diagram is 1130 svg units wide and 200 high. If a box is too tall for a line, it will overflow. If it is too wide for a line then the program gives up in disgust.

These two boxes will draw essentially the same thing

  <box text="T" modifier=R½" bars="2"/>
  <box bars="2">
    <text class="main" x="0" y="0">T
    <text class="modifier" x="16" y="8">R½
  </box>

I do not support all of svg, but I support a large enough subset that I can draw what I need to. You may include animation elements for animated diagrams

Don't use a box with both a "text" element and svg children. I don't know what will happen.

A <box> element may contain an arbitary number of svg elements, and it may also contain <popup-boxes>.

The <meanwhile> element.

The <meanwhile> specifies that two (or more) actions take place simultainiously. Often the 1s will do one thing, and the others something else. It draws a curly brace above all its children to show they all happen at once.

A <meanwhile> has its own rectangle on the output canvas in which all its children are drawn.

A <meanwhile> supports most of the attributes used by boxes, with the expection of the 'text' attributes.

Attributes
headerThis specifies a header to be displayed on the upper line of the box. If the header does not contain the "|" character then the header will be centered in the box. If it contains one "|", as for example "left|right" the the text to the left of the "|" will be displayed on the left, while the remainder is displayed to the right of the box. If there are two "|" then the three bits of text will be either left-adjusted, centered, or right-adjusted. Etc.
notes-topThis is very similar to a header but uses a different type size.
notes-bottomThis is very similar to notes-top but is placed at the bottom of the box.
notes-bottom2This is very similar to notes-bottom but is placed one line up from the bottom of the box.
strainThis is for English Country Dance and is used to mark the beginning of a new strain of music with this box. It usually has a value like "A1" or "B2".
line-break-afterForce a line break after this box. Usually k2s will pack as many boxes as it can onto one line of the output canvas (with a few constrains), but if the user needs better control this can force a linebreak where the user wants it.
show-start-barsWhen there's a repeat later in the diagram that repeat may specify which bars are to be repeated. This explicitly marks the box with the bar-count for the start of the box.
show-end-barsWhen there's a repeat later in the diagram that repeat may specify which bars are to be repeated. This explicitly marks the box with the bar-count for the end of the box.
barsSpecifies the number of bars needed to perform the figure displayed in the box. This is a required attribute.
dividerk2s usually draws a divider after every box, the divider varies depending on if the box ends with the bar-count a multiple of 8 (in which case a solid line is drawn), a multiple of 4 (a dashed line), or a multiple of 2 (a dotted line). If you don't want a divider drawn specify 'divider="false"'.

A <meanwhile> element may contain an arbitary number of <box> elements, and it may also contain one <popup-boxes>.

The <sequence> element.

The <sequence> specifies that two (or more) actions take place one after another to make up a figure.

A <sequence> has its own rectangle on the output canvas in which all its children are drawn.

A <sequence> supports most of the attributes used by meanwhile, with the expection of the 'bars' attribute.

Attributes
headerThis specifies a header to be displayed on the upper line of the box. If the header does not contain the "|" character then the header will be centered in the box. If it contains one "|", as for example "left|right" the the text to the left of the "|" will be displayed on the left, while the remainder is displayed to the right of the box. If there are two "|" then the three bits of text will be either left-adjusted, centered, or right-adjusted. Etc.
notes-topThis is very similar to a header but uses a different type size.
notes-bottomThis is very similar to notes-top but is placed at the bottom of the box.
notes-bottom2This is very similar to notes-bottom but is placed one line up from the bottom of the box.
strainThis is for English Country Dance and is used to mark the beginning of a new strain of music with this box. It usually has a value like "A1" or "B2".
line-break-afterForce a line break after this box. Usually k2s will pack as many boxes as it can onto one line of the output canvas (with a few constrains), but if the user needs better control this can force a linebreak where the user wants it.
show-start-barsWhen there's a repeat later in the diagram that repeat may specify which bars are to be repeated. This explicitly marks the box with the bar-count for the start of the box.
show-end-barsWhen there's a repeat later in the diagram that repeat may specify which bars are to be repeated. This explicitly marks the box with the bar-count for the end of the box.
dividerk2s usually draws a divider after every box, the divider varies depending on if the box ends with the bar-count a multiple of 8 (in which case a solid line is drawn), a multiple of 4 (a dashed line), or a multiple of 2 (a dotted line). If you don't want a divider drawn specify 'divider="false"'.

A <sequence> element may contain an arbitary number of <box> elements, and it may also contain one <popup-boxes>.

The <popup-boxes> element.

The <popup-boxes> allows you to build a more complete description of a figure. I use it mostly to flesh out repeats.

If a <box> contains a <popup-boxes> element, then at the bottom of the box a small magnifying glass will be drawn. If you move the mouse to this area then another set of boxes will appear on top of the crib diagram showing a more detailed description of the figure.

This element has no attributes.

A <popup-boxes> element may contain an arbitary number of <box>, <meanwhile>, or <sequence> elements. It may not contain another <popup-boxes> element.

Example

Result

GRUNION RUN 4×32 R George Williams, 2026 4 Couple longways morris hey A1 1 1 2 2 3 3 1 A2 2 dance up snowball N 2 3 1 1 3 2 S 2 3 1 1 3 2 B1 1 S 4 1 1 2 3 3 2 B2 2 3 1 1 3 2 2 T B 3 3 1 1 3 1 T B T 1 1 4 4

Source

<krcd
    header-left="GRUNION RUN"
    header-right="4×32 R"
    footer-left="George Williams, 2026"
    footer-right="4 Couple longways" >
  <box strain="A1" bars="8" notes-bottom="morris hey" >
    <g transform="translate(0,20)">
    <text class="box-header" x="0" y="0">1⃝</text>
    <line class="line" x1="3" y1="-1" x2="-2" y2="4" />		<!-- sw -->
    </g>
    <g transform="translate(0,-20)">
    <text class="box-header" x="0" y="0">1⃞</text>
    <line class="line" x1="1" y1="-20" x2="-4" y2="-25" />	<!-- nw -->
    </g>

    <g transform="translate(40,15)">
    <text class="box-header" x="0" y="0">2⃝</text>
    <line class="line" x1="0" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,-15)">
    <text class="box-header" x="0" y="0">2⃞</text>
    <line class="line" x1="1" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    </g>

    <g transform="translate(80,20)">
    <text class="box-header" x="0" y="0">3⃞</text>
    <line class="line" x1="22" y1="1" x2="27" y2="6" />		<!-- se -->
    </g>
    <g transform="translate(80,-20)">
    <text class="box-header" x="0" y="0">3⃝</text>
    <line class="line" x1="20" y1="-17" x2="25" y2="-22" />	<!-- ne -->
    </g>

    <circle r="20" cx="32" cy="-70" class="line" />
    <circle r="20" cx="72" cy="-70" class="line" />

    <circle r="20" cx="32" cy="50" class="line" />
    <circle r="20" cx="72" cy="50" class="line" />

    <line class="line" x1="18" y1="36" x2="30" y2="24" />
    <line class="line" x1="18" y1="-56" x2="30" y2="-44" />

    <g transform="translate(0,50)">
    <circle class="filled" cx="0" cy="0" r="3"/>
    <circle class="line" cx="0" cy="0" r="7"/>
    </g>

    <path class="hidden" d="M 30,80 h 3" />
  </box>
  <box bars="2" header="1" text="2⃕" strain="A2" divider="false"/>
  <box bars="2" notes-bottom2="snowball" notes-bottom="dance up" >
    <text class="main" x="0" y="0" >←</text>
    <text class="notes" x="18" y="6">N</text>
  </box>
  <box bars="2" divider="false">
    <text class="main" x="-5" y="5" >←</text>

    <g transform="translate(40,75)">
    <text class="box-header" x="0" y="0">2⃝</text>
    <line class="line" x1="0" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,45)">
    <text class="box-header" x="0" y="0">3⃝</text>
    <line class="line" x1="0" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,15)">
    <text class="box-header" x="0" y="0">1⃝</text>
    <line class="line" x1="0" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,-15)">
    <text class="box-header" x="0" y="0">1⃞</text>
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    <line class="line" x1="1" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    </g>
    <g transform="translate(40,-45)">
    <text class="box-header" x="0" y="0">3⃞</text>
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    <line class="line" x1="1" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    </g>
    <g transform="translate(40,-75)">
    <text class="box-header" x="0" y="0">2⃞</text>
    <line class="line" x1="1" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    </g>
  </box>
  <box bars="2" >
    <text class="main" x="-5" y="6" >S</text>

    <g transform="translate(40,75)">
    <text class="box-header" x="0" y="0">2⃝</text>
    <line class="line" x1="0" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,45)">
    <text class="box-header" x="0" y="0">3⃝</text>
    <line class="line" x1="0" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,15)">
    <text class="box-header" x="0" y="0">1⃝</text>
    <line class="line" x1="0" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,-15)">
    <text class="box-header" x="0" y="0">1⃞</text>
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    <line class="line" x1="1" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    </g>
    <g transform="translate(40,-45)">
    <text class="box-header" x="0" y="0">3⃞</text>
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    <line class="line" x1="1" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    </g>
    <g transform="translate(40,-75)">
    <text class="box-header" x="0" y="0">2⃞</text>
    <line class="line" x1="1" y1="-9" x2="-7" y2="-9" />	<!-- left -->
    </g>
  </box>
  <meanwhile bars="8" strain="B1" >
    <box header="1⃞" text="S" modifier="4" />
    <box >
      <g transform="translate(-5,-15)">
	<text class="box-header" x="0" y="0" style="fill: grey;">1⃞</text>
      </g>
      <circle class="line" cx="7" cy="-25" r="20" />
      <circle class="line" cx="7" cy="15" r="20" />
      <line class="line" x1="21" y1="1" x2="36" y2="16" />

      <g transform="translate(40,15)">
      <text class="box-header" x="0" y="0">1⃝</text>
      <line class="line" x1="4" y1="-17" x2="-1" y2="-22" />	<!-- nw -->
      </g>
      <g transform="translate(40,80)">
      <text class="box-header" x="0" y="0">2⃝</text>
      <line class="line" x1="13" y1="-20" x2="13" y2="-27" />	<!-- up -->
      </g>
      <g transform="translate(40,50)">
      <text class="box-header" x="0" y="0">3⃝</text>
      <line class="line" x1="13" y1="-20" x2="13" y2="-27" />	<!-- up -->
      </g>

      <g transform="translate(40,-45)">
      <text class="box-header" x="0" y="0">3⃞</text>
      <line class="line" x1="2" y1="0" x2="-3" y2="5" />		<!-- sw -->
      </g>
      <g transform="translate(40,-75)">
      <text class="box-header" x="0" y="0">2⃞</text>
      <line class="line" x1="2" y1="0" x2="-3" y2="5" />		<!-- sw -->
      </g>
    </box>
  </meanwhile>
  <box bars="2" strain="B2" >
    <text class="main" x="85" y="5" >→</text>

    <g transform="translate(40,75)">
    <text class="box-header" x="0" y="0">2⃝</text>
    <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,45)">
    <text class="box-header" x="0" y="0">3⃝</text>
    <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,15)">
    <text class="box-header" x="0" y="0">1⃝</text>
    <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    </g>
    <g transform="translate(40,-15)">
    <text class="box-header" x="0" y="0">1⃞</text>
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
    </g>
    <g transform="translate(40,-45)">
    <text class="box-header" x="0" y="0">3⃞</text>
    <line class="line" x1="13" y1="-20" x2="13" y2="-28" />	<!-- up -->
    <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
    </g>
    <g transform="translate(40,-75)">
    <text class="box-header" x="0" y="0">2⃞</text>
    <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
    </g>
  </box>
  <meanwhile bars="4" >
    <box header="2" text="T" modifier="B" />
    <box header="3" >
      <g transform="translate(40,45)">
      <text class="box-header" x="0" y="0">3⃝</text>
      <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
      </g>
      <g transform="translate(40,15)">
      <text class="box-header" x="0" y="0" style="fill: grey;">1⃝</text>
      </g>
      <g transform="translate(40,-15)">
      <text class="box-header" x="0" y="0" style="fill: grey;">1⃞</text>
      </g>
      <g transform="translate(40,-45)">
      <text class="box-header" x="0" y="0">3⃞</text>
      <line class="line" x1="24" y1="-9" x2="31" y2="-9" />	<!-- right -->
      </g>
      <text class="modifier" x="85" y="47" >→</text>
      <g transform="translate(135,47) rotate(-90)" >
      <text class="modifier" x="0" y="0" >⟲</text>
      </g>
      <text class="modifier" x="85" y="-43" >→</text>
      <g transform="translate(135,-43) rotate(-90)" >
      <text class="modifier" x="0" y="0" >⟳</text>
      </g>
    </box>
    <box header="1" >
      <text class="main" x="0" y="0">T</text>
      <text class="modifier" x="18" y="10">B</text>
      <text class="modifier" x="5" y="30" >→</text>
    </box>
  </meanwhile>
  <box bars="2" >
    <text class="main" x="4" y="0">T</text>
    <text class="modifier" x="22" y="10">E½</text>

    <g transform="translate(0,45)">
    <text class="box-header" x="0" y="0">1⃝</text>
    <line class="line" x1="13" y1="3" x2="13" y2="10" />	<!-- down -->
    <line class="line" x1="24" y1="-9" x2="50" y2="-9" />	<!-- right -->
    </g>
    <g transform="translate(0,-50)">
    <text class="box-header" x="0" y="0">1⃞</text>
    <line class="line" x1="13" y1="-21" x2="13" y2="-28" />	<!-- up -->
    <line class="line" x1="24" y1="-9" x2="52" y2="-9" />	<!-- right -->
    </g>

    <g transform="translate(50,45)">
    <text class="box-header" x="0" y="0">4⃝</text>
    <line class="line" x1="13" y1="-20" x2="13" y2="-27" />	<!-- up -->
    </g>
    <g transform="translate(50,-50)">
    <text class="box-header" x="0" y="0">4⃞</text>
    <line class="line" x1="13" y1="2" x2="13" y2="9" />		<!-- down -->
    </g>
  </box>
</krcd>