This is a tutorial on authoring legal styles for the Juris-M research manager. To illustrate the process, we will walk through the creation of a module for the sunken kingdom of Atlantis, an imaginary jurisdiction with just two citation forms:
The first form is for citations to court judgments (the Case type, in Juris-M terms). The second is to the official record of original legislation (corresponding to the Statute type with theflag enabled).
You may wish to create the module yourself as you read through this document. The style editor will overlay the tutorial when it is opened, but you can toggle the document view at any time using the info icon above.
Juris-M style modules are written in a variant of the Citation Style Language (CSL). No prior programming experience is necessary: if you have some familiarity with HTML and the patience to read a little documentation, you will find that CSL is rather easy to work with.
You should budget at least an hour to work through the tutorial. The sections below provide code blocks that can be pasted into a template to quickly create the sample style for Atlantis; but you should take time to study the comments and be sure that you understand the structure and logic of the code.
Begin by loading the style module for Atlantis, which (as you may have anticipated) is a subjurisdiction of Laputa. Two steps are required to load the style:
does not yet exist, so the editor will load a
template when you first call it. At the top of
the file, you will find a
prefix is our shorthand for "CSL code block").
Some of the details are filled in automatically
(zz is the ISO code
for imaginary countries).
<info> <title>ZZ, Atlantis</title> <id>https://citationstylist.org/modules/juris-zz:zz</id> <link href="https://citationstylist/modules/juris-zz:zz" rel="self"/> <link href="https://juris-m.github.io" rel="documentation"/> <author> <name>YOUR-NAME-HERE</name> <email>YOUR-EMAIL-ADDRESS-HERE</email> </author> <category citation-format="note"/> <category field="law"/> <summary>Juris-M style module for ZZ, Atlantis</summary> <updated>2013-01-26T22:06:38+00:00</updated> <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights> </info>
To get started, fill in your name and email address to take credit for your work. Press thebutton, wait for validation to complete, and then press .
If all goes well, the editor will save the change to your personal GitHub repository and report success (if there is an error, wait a minute and try again—it sometimes takes a little time for GitHub to catch up with us the first time around).
After loading the style, select the Sampler tab to preview the current output of the module for the default Case type. The items look something like this:
Use the dropdown selector to choose the Statute type, which displays the same unsightly "citations":
Each bracketed term comes from a separate CSL macro (a component) supplied by the legal style module. Components are joined together in the style that calls the module, with code that we will call the scaffolding.
In our module
the scaffolding is contained in
cs:citation element at the
bottom of the file. We will not touch this block
in this tutorial—it is, in
fact, not part of the module code. In
production, our module will be called by
another, more general style (Chicago Full
Note, APA, OSCOLA, etc.), and
the calling style will supply its own
The module components consist of a set of juris-prefixed macros. Here is the full list of them, all of which must be defined:
Components are the building blocks from which we will construct printed citations. To that end, we need to visualize the samples in terms of the macro component categories: title, main, locator and tail. Through our Juris-M-colored spectacles, the samples look something like this:
The secondary pinpoint to page 113 in the second sample (marked by a brighter-red highlight) is small wrinkle in the design that will be discussed in detail a bit later. Meanwhile, note that the division between the blocks depends only on the position of the pinpoint locator: the components are purely visual units, and have no special semantic significance.
As noted above, we need just two citation types
and Statute. This reflects actual
practice, where a sub-jurisdiction may have
special citation requirements for only certain
types of material. We can limit our module to
these two types by inserting the following code
as the last element inside
<law-module types="legal_case legislation"/>
The name used for the Juris-M Case type in CSL code is legal_case, and that for the Statute type is legislation—see below for a full list of the Juris-M legal types and their CSL equivalents.
When the style is validated with this new code, all but these two item types will be disabled in the the dropdown menu in the Sampler.
When citations are processed in a production environment, this module-level item-type constraint will have the following effect:
For example, if we input an item of the Hearing type (hearing), the processor will ignore our module code, and instead attempt to use the Laputa module, if one exists; and if it has no luck there, it will use the default code of the original "ancestor" style that sent out the call for modular code.
For reference, the Juris-M legal item types and their CSL equivalents are as follows:
|Juris-M label||CSL variable|
We are now almost ready to begin composing citations; but first, we will set up the test data for our samples.
We will need some test data to preview the code we are about to write for the components. The editor will provide supply default values for the various CSL input variables, but the automatically generated content can be difficult to interpret in the display. Let's begin by setting up the values that we expect to see in the finished citations.
In the Sampler, set the item type to Case, and click on the bubble. In the popup that appears, enter Int’l Shoe Co. v. Wash., and click on the button. Nothing will change in the citation display (yet), but you can check that the value has been saved by clicking on the bubble again.
Proceed in the same fashion for the remaining citation data. Here are the values to set for Case:
In production data, you may prefer to enter the full name of the Lawyer's Edition, and the value of will be set to the internal identifier for Supreme Court. The Juris-M Abbreviation Filter can be used to transform full-form entries and internal codes to the correct citation form; but for testing, we are good to just set the literal abbreviated values in these fields.as
Here are the values to set in the Statute view:
|(any value—this is a toggle)|
|& sec. 10 | 115|
Here again, in production data you may prefer to enter Statutes at Large as the value of the field. We will use the abbreviated value for testing, but we will explain how to enable support for the Juris-M Abbreviation Filter below.
Now that our sample data is in place, we are ready to start coding the module!
To include the title in full-form citations, replace the juris-title macro with the following code:
<macro name="juris-title"> <choose> <if type="legal_case"> <text variable="title" form="short"/> </if> <else> <text variable="title"/> </else> </choose> </macro>
As mentioned above, the Juris-M Abbreviation
Filter is able to abbreviate field content. When
attribute is set on the title of a legal
citation type, the Filter will attempt to apply
abbreviations from an external database of words, phrases
and full titles.
In the legal style
the titles of legislation are never abbreviated.
Accordingly, we use a
conditional statement to limit abbreviation to the
You can read more about condition statements in the CSL Specification, linked in the Docs menu above.
After validation, the first-listed item in the Sampler with the Case type is selected should look like this:
When the Statute type is selected, it should show this:
The titles are drawn from theand fields; drag them to the Excluded fields box to remove them, and restore them by dragging them back. This is a handy way of testing our module code with various combinations of input.
form="short"is applied to the the title variable of a non-legal item, Juris-M will first attempt to render title-short (the field), and fall back to title only if no value is found there.
In the previous section,
component tested for item type, and rendered the
title in the appropriate form with
cs:text element. Turning to
component, we note that the Case
and Statute types will again require
(very) different treatment:
Accordingly, we apply a test for item type in the code for juris-main.
introduces two new CSL
elements. The volume
variables must be rendered
cs:number (rather than
cs:text) because these
are numeric variables in the Juris-M
flavour of CSL. You can check the category of
the variables available in each item type by
Field Maps menu at the top of this page.
The three elements rendered
by juris-main in
the Case type are joined together by
wrapping them in a
element. We add a space between each element
delimiter=" " on
the group. (In passing, note the use of
form="short" attribute, which
will apply an abbreviation to the reporter name
if one is available.)
In the Atlantis jurisdiction, laws passed in 1978 and after are assigned a unique Public Law Number in the official gazette, which should be given the label “Pub. L. No.”. Laws passed before 1978 were numbered by "chapter" in each legslative session, and should be labelled with “ch.”.
number field recognizes a set
of short-code prefixes that map to
pre-defined labels. We can use a short-code
prefix in our input data to distinguish between
the two types of numbering in the official
gazette. Short-code prefixes are removed from
the field, but they set a label name for which
we can test, and the label can be rendered
When no short-code prefix is given,
number="number" will return
because “number” is the default label
value for the
In our test data, we have marked
the value with the short-code prefix
ch., which changes the
label associated with the
chapter: with our input
data, the test
false, and the component will
render the chapter label.
From the user's perspective, all that is needed is to set the ch. prefix on the of pre-1978 legislation items of Atlantis; the citation processor and the module will take care of the details.
That said, we are not quite finished with
component. The label short-code is not used
directly: it is written in the form specified on
cs:label element, using data
supplied by the standard CSL locales. The
standard abbreviation of
is chap., as we can
see in the citation shown in
To get the form we expect to see
citations, add this block of code immediately after the closing
tag of the
<locale> <terms> <term form="symbol" name="chapter">ch.</term> </terms> </locale>
This will override the standard locale for testing purposes—but note that this is non-modular code: the "ancestor" style that calls our module will apply its own locale settings when rendering the component.
To learn more about CSL locales, refer to the CSL Specification, linked in the Docs menu at the top of this page.
Code for the juris-main component
<macro name="juris-main"> <choose> <if type="legal_case"> <group delimiter=" "> <number variable="volume"/> <text variable="container-title" form="short"/> <number variable="page-first"/> </group> </if> <else> <choose> <if number="number"> <group delimiter=" " suffix=","> <text value="Pub. L. No."/> <number variable="number"/> </group> </if> <else> <group delimiter=" " suffix=","> <label variable="number" form="symbol"/> <number variable="number"/> </group> </else> </choose> </else> </choose> </macro>
Short-codes recognized on the number variable
Our target citation forms differ considerably in their tail portion.
The Statute type also has the wrinkle that we adverted to earlier, highlighted in red. We will now need to deal with that as well.
The common feature of the two citations is the trailing parenthetical. The year fields (issued variable. The court name is drawn from the field corresponds to the Juris-M CSL authority variable. That variable is not present on the Statute type (since legislation is a product of the whole state), so we won't need to exclude it with a condition.and respectively) both map to the CSL
form="short" attribute on
cs:institution element. For
full details on the
element, see the Juris-M CSL Specification
Supplement, linked in the Docs menu at
the top of this page.
block, we render the elements of the reporter
citation needed for Statute items. To
cover the “wrinkle” posed by the
additional pinpoint (113) we use
variable. (This is set in word-processor, in the ordinary
field by setting it off with a
| vertical bar
character—see the Juris-M CSL
Specification Supplement, linked from
the Docs menu at the top of this page,
for details and an example.)
<macro name="juris-tail"> <group delimiter=" "> <choose> <if type="legislation"> <number variable="volume"/> <text variable="container-title" form="short"/> <group delimiter=", "> <number variable="page-first"/> <text variable="locator-extra"/> </group> </if> </choose> <group delimiter=" " prefix="(" suffix=")"> <names variable="authority"> <name/> <institution institution-parts="short"/> </names> <date form="text" date-parts="year" variable="issued"/> </group> </group> </macro>
In the short-form citations shown for case, we initially see this:
As the scaffolding implements the Baby Blue style, this is not correct: supra should not be used for back-references to a case citation. The discrepancy is due to inclusion of the Document Name field. Drag it to the right to remove it from the fields used in the Sampler, and the cites will change to the correct structure:
The Statute type shows roughly the same thing—the only difference is that the title placeholder is set in a roman rather than italic type:
To show the field content for these entries, we must define the juris-title-short component.
To gracefully negotiate the two layers of
abbreviation described in the previous section,
component requires a little more code than its
long-form cousin, but the logic to be applied is
is tightly bound to the Short Title
field, and it will test
the field is empty. Remembering that
form="short" attribute should
be used only on
the legal_case type,
the following conditions
cs:text elements will produce
the effect we're after:
<macro name="juris-title-short"> <choose> <if match="all" type="legal_case" variable="title-short"> <text variable="title-short" form="short"/> </if> <else-if type="legal_case"> <text variable="title" form="short"/> </else-if> <else-if variable="title-short"> <text variable="title-short"/> </else-if> <else> <text variable="title"/> </else> </choose> </macro>
To test the logic, set the Sampler to the Case type, and drag the field out of the Included fields box. The style should use the content of the field when the shortened name is not available.
For the juris-main-short component, we delve again into our copy of The Atlantis Guide, and confirm the short form of our two sample citations. When a pinpoint locator is used, it should be written as follows (highlighting added to mark the portion to be rendered by the juris-main-short component):
Well, how about
component is completely empty in Statute
citations. Accordingly, we set an empty
condition for that type of input, and
cs:group to join the two
elements needed for citations of the Case
<macro name="juris-main-short"> <choose> <if type="legislation" variable="gazette-flag" match="all"/> <else> <group delimiter=" "> <number variable="volume"/> <text variable="container-title" form="short"/> </group> </else> </choose> </macro>
There is not much to see here either. Neither of the citation forms in the Atlantis jurisdiction place anything after the pinpoint locator in short-form citations, so this component also returns an empty string.
<macro name="juris-tail-short"> <text value=""/> </macro>
Locators consist of just two elements—a label and a pinpoint locator—yet they have surprisingly complex formatting requirements. The form of labels varies across citation styles and across jurisdictions. At the same time, the joining punctuation used depends on both the surrounding context and the form of the label. In Juris-M modules, we need only worry about the label to be used in cites within our specific jurisdiction. As we will see, the scaffolding of the parent style will supply appropriate joining punctuation.
The locators for our Atlantis style can be coded like this:
<group delimiter=" "> <choose> <if locator="page"/> <else> <label variable="locator"/> </else> </choose> <number variable="locator"/> </group>
cs:if statement will
render nothing (no label) when the locator is a
page; otherwise, it will print the appropriate
label, separated from the locator itself by a
single space. The form of the label (as long,
short or symbolic) will be set by the parent
style and its locale, so we omit
That's it for the module code: the parent style scaffolding will assign label forms and join the components with correct punctuation.
There is one important detail that is not illustrated in these examples. In many non-US citation styles in the common law world, paragraph numbers are indicated by enclosing each number in a separate pair of braces. Quoting the OSCOLA guide:
To implement this rule, add the following block
at the top of the module code, immediately after
<locale> <terms> <term name="paragraph" form="static">[%s]</term> </terms> </locale>
Then use code like the following for the locator:
<group delimiter=" "> <choose> <if locator="page"/> <else-if locator="paragraph"> <label variable="locator" form="static"> </else-if> <else> <label variable="locator"/> </else> </choose> <number variable="locator"/> </group>
When the processor renders a label with the
placeholder %s immediately before its
associated variable, the processor will combine
the two by substituting the value for the
placeholder. The effect of
form="static" attribute is to
prevent the parent style from modifying the form
of this particular label.
And ... that's it! Our freshly minted module should be producing correct citations for both item types, adapting gracefully to changes in field content and in the pinpoint identifiers. Check it out—you should see results like those shown below.
This tutorial has introduced the modular architecture of the Juris-M legal style system, and covered the essential structures needed for style authoring. There is more to Juris-M CSL than we have been able to cover here, but the links under the Docs link above provide a comprehensive treatment of the language. If you get stuck, submit what you have to GitHub, and we can discuss possible solutions there.