1. Installing
If you use Bikeshed infrequently, or are okay with requiring a network roundtrip every time you invoke Bikeshed, you probably want to use the Bikeshed API instead. In return, the API version is always up-to-date, so you don’t have to remember to update things yourself.
If you want to run a local copy of Bikeshed rather than use the cgi version, it’s pretty easy to install.
You need to install Python 2.7, PIP, and a few other support libraries before installing Bikeshed itself. Here is how to do this on Debian-based Linuxen (anything using apt), OS X, and Windows 7/8/10:
1.1. Linux steps
$ sudo apt-get install python2.7 python-dev python-pip python-wheel libxslt1-dev libxml2-dev
The apt-get command works on Debian-based systems like Ubuntu; if you work on some other type of system, and can figure out how to get things working on your own, let me know and I’ll add instructions for your system.
Then, we’ll need to install lxml and Pygments.
$ sudo pip install pygments $ sudo pip install lxml
Important: If this command reports that you already have lxml, instead run:
$ sudo pip install lxml --upgrade
That’ll spew a lot of console trash, but don’t worry about it.
In some installations you’ll need to also upgrade setuptools for html5lib's entertainment:
$ sudo pip install lxml setuptools --upgrade
From here, you can proceed to §1.5 Common steps.
1.2. OS X steps
Note: If you’re on a relatively modern Mac you should be able to proceed directly to §1.5 Common steps.
These instructions assume that you have Mac Ports or Homebrew installed. If you successfully install Bikeshed using some other method, please contribute to this documentation.
1.2.1. Mac ports
First, get the right packages installed onto your system:
sudo port install python27 py27-pip py27-lxml py27-html5lib py27-cssselect py27-libxslt py27-libxml2 py27-pygments
Then, activate the python version you just installed as the one the system should use:
sudo port select --set python python27
(If you get ImportError: No module named six when you first run Bikeshed, additionally run sudo port install py27-six.)
1.2.2. Homebrew
Install the Homebrew version of Python and Pip:
brew install python
Install the XCode command-line tools:
xcode-select --install
Install or update lxml and Pygments.
$ pip install pygments lxml --upgrade
That’ll spew a lot of console trash, but don’t worry about it.
From here, you can proceed to §1.5 Common steps.
1.3. Windows steps
Tested on Windows 7, 8/8.1 & 10
-
Install the latest Python 2.7.
-
Run the following in an elevated command prompt (change the path if your location is different)
setx /m PATH "%PATH%;C:\Python27;C:\Python27\Scripts"
-
If using Python 2.7.8 or older, install PIP by saving get-pip.py and just double clicking the file.
-
Run the following in a command prompt to install or update lxml and Pygments
python -m pip install pygments lxml==3.6.0 --upgrade
From here, you can proceed to §1.5 Common steps.
1.4. Android + Termux steps
This is how to set up bikeshed on your android phone or tablet using Termux.
-
Install Termux from Google Play or F-Droid.
-
Install python, git, a c compiler, and the native dependencies:
$ apt install python2 python2-dev clang libxml2-dev libxslt-dev git
-
Install the Python dependencies:
$ pip2 install pygments lxml --upgrade
From here, you can proceed to §1.5 Common steps.
1.5. Common steps
With the dependencies in place, you can now install the Bikeshed repository itself. Run the following in your favorite command line:
$ git clone https://github.com/tabatkins/bikeshed.git
(This’ll download bikeshed to a bikeshed folder,
created wherever you’re currently at.
If you think you might want to commit back to Bikeshed,
instead download it over SSH.
I won’t explain how to do that here.)
Finally, run:
For Linux/OSX (Omit the sudo for OSX under Homebrew):
$ sudo pip install --editable /path/to/cloned/bikeshed $ bikeshed update
On Windows:
$ python -m pip install --editable /path/to/cloned/bikeshed $ bikeshed update
On Termux:
$ pip2 install --editable /path/to/cloned/bikeshed $ bikeshed update
This’ll install Bikeshed,
making it available to your Python environment as the bikeshed package,
automatically add a bikeshed command to your path,
and then update your data files to the latest versions.
To update bikeshed to its latest version at any time, just enter Bikeshed’s folder and run:
$ git pull --rebase $ bikeshed update
This’ll pull the latest version of Bikeshed, and ensure that you’re looking at the latest version of the data files, rather than whatever stale version is currently sitting in the repo.
(If anything doesn’t work in here, let me know and I’ll fix it. These instructions have worked for a lot of people on all OSes, but it’s possible that you’ll run into a new error, because computers are terrible.)
1.6. Travis CI steps
To use bikeshed on Travis CI's github integration, you’ll need the following .travis.yml commands:
sudo: false language: python python: - "2.7" install: - pip install pygments lxml setuptools --upgrade - git clone https://github.com/tabatkins/bikeshed.git - pip install --editable $PWD/bikeshed - bikeshed update script: # Invoke bikeshed here, at your own leisure. E.g.: - bikeshed spec
2. The Command Line Interface
Locally-installed Bikeshed is invoked via the command-line. There’s a bunch of options, but you’ll only use a few in day-to-day use.
2.1. Global Options
There are a few options that apply to many different options, so they’re specified before the individual commands:
-hor--help-
Shows the help message for the current command. Can be run without any command, like
bikeshed -hto show the list of valid commands and the global flags, or after a command, likebikeshed spec -hto show the help text for that command in particular. -for--force-
A very useful command,
-fmakes fatal errors non-fatal. Bikeshed’s categorizes errors as "fatal" if they’re clearly mistakes, or will cause some variety of data loss in your spec; regardless, it can generally recover gracefully from them. If you just need to generate a spec quickly, and will fix the error later,-fwill let you do that.It’s also quite useful when fixing a freshly-written (or ported) spec that might have a lot of errors in it; rather than seeing only the very first error, running with
-fwill show you all the errors, so you can fix them in whatever order you like. (In that case, running with-qor-qqmight also be useful, to suppress the non-fatal errors temporarily.) -qor--quiet-
The
-qflag suppresses one level of error messages. It can be passed multiple times to suppress additional levels, in the order "warnings", then "link errors", then "fatal errors". -sor--silent-
The
-sflag suppresses all console output from Bikeshed, regardless of source. (It’s more powerful than-q, as it’ll also suppresses things like the success/failure message.) -dor--dry-run-
The
-dflag prevents Bikeshed from actually writing anything to disk. It does everything else, just skips that final "save" operation. --print= [ plain | console | markup ]-
Specifies how Bikeshed should output its messages. Default is "console", which outputs colored text using console color codes. "plain" outputs the same text as "console", but without any color codes (which look like gibberish if you’re not ouputting to a console). "markup" outputs the text in a light markup structure (suitable for parsing as HTML), for easier parsing of the output by tools.
2.2. bikeshed spec
The spec command is the most common one you’ll use.
It turns a Bikeshed source file
into an output HTML file.
The rest of this document mostly describes how to format a source file
for use with this command.
Most of the time you can just run bikeshed spec and things will "just work"
as long as your source file has the .bs extension.
Relevant flags:
--gh-token=TOKEN-
If you’re using Inline GitHub Issues heavily, you might run into the GitHub rate limit. You can generate an OAuth token at https://github.com/settings/tokens and then pass it to Bikeshed via this flag to raise your limit considerably.
-lor--line-numbers-
If you’re having trouble locating the source of an error in your code, run Bikeshed with this flag and almost all errors will report the source line number they appear at (or somewhere very close - it’s per-element).
This code is unfortunately forced to be fairly hacky, and has the potential to lightly corrupt your file (inserting extra debugging info into plain text that just happens to look like markup), so it automatically triggers a dry-run, as if you’d specified
--dry-run. When you’re done debugging, just run again without this flag to actually get some output.
After any flags,
you can optionally specify the input file path and output file path.
Both of these can usually be omitted;
if you omit the output file,
it’ll just output to a file with the same name as the input file,
but with the extension changed to .html;
if you omit the input file,
it’ll search thru the current directory
and assume you want the first file with a Bikeshed extension (.bs).
If you want to feed Bikeshed from stdin
or have it output to stdout,
just use - as the appropriate filename.
2.3. bikeshed watch
The watch command is identical to the spec command,
except it sets up a watcher
and auto-rebuilds the spec every time it changes.
With this turned on,
you can edit with a simple save->refresh cycle,
rather than having to do save->build->refresh.
It accepts all the same arguments as spec.
(Tho using stdin/stdout might get a little weird.)
Use Ctrl-C to stop the watcher (or whatever key combo kills the currently running process in your console).
2.4. bikeshed template
The template command outputs a minimal "skeleton" document to stdout.
It’s useful to get started with Bikeshed,
without having to remember what all the required metadata is.
On a Linux-like command line, it should be used like:
$ bikeshed template > index.bs
2.5. bikeshed echidna
The echidna command hooks into the W3C’s Echidna auto-publishing system,
letting you publish W3C specs from the command-line,
rather than having to go thru a staff contact.
Note: Currently, only Working Drafts (not including FPWD) can be published via Echidna.
It’s invoked similarly to bikeshed spec,
with three required flags:
--u USERNAME-
Your W3C username
--p PASSWORD-
Your W3C password
--d DECISION_URL-
A link to a publicly-visible message approving the publication of this draft.
After the flags,
you can optionally specify the input file path,
just like for bikeshed spec;
if omitted,
it selects a file automatically in the same way.
Bikeshed then builds the spec normally, performs a little bit of fixup for common issues that PubRules complains about, and submits the spec to Echidna. It will print out a URL for you to check on the progress of your publication; it should complete in a few seconds.
Most likely you’ll have some PubRules errors when you check your progress;
fix those
(ask in irc.w3.org#pub for help if needed)
then just run bikeshed echidna again.
2.5.1. Echidna Hooks
Bikeshed’s default publication behavior is usually sufficient,
but if you need to customize it in some way,
there are a few hooks you can use
(assuming you can write Python).
In an include file named bs-extensions.include,
provide an implementation of the following methods
(check the default version of this file for the default implementations,
for the methods you don’t want to change):
BSPrepTR(doc)-
This method is called after processing is done, when the document is ready to be packed up and sent to Echidna. Here, you can perform whatever final post-processing is required.
BSPublishAdditionalFiles(files)-
This method allows you to specify what files should be included in the publishing bundle. It must return an array of additional files/folders; each entry must either be a string, referring to a file/folder in the spec’s directory or subdirectories, or a tuple of 2 strings, the first of which points to a file outside the spec’s directory, and the second of which provides the path the file should have within the spec’s directory.
The
filesvalue provides the default values, which you probably want to just extend, rather than fully replace. It defaults to["images", "diagrams", "examples"], indicating that those folders, if present, will be included.For example, as stated in the example forBSPrepTR(), the CSSWG needs to include its stylesheet in with its specs. To do so, it just needs to add the entry["../default.css", "default.css"]to thefilesarray, indicating that Bikeshed should grab thedefault.cssfile from the parent directory, and put it in the spec’s directory (in the bundle) with the same name.
2.6. bikeshed update
The update command updates Bikeshed’s datafiles,
which it uses for autolinking and similar things.
By default it’ll update all of its datafiles,
but if you want to update only particular ones,
you can pass any or all of the following flags:
-
--anchorsto update Bikeshed’s "anchor data" - a list of all the definitions and headers it knows about. -
--biblioto update Bikeshed’s bibliography database. -
--caniuseto update Bikeshed’s CanIUse.com information. -
--link-defaultsto update Bikeshed’s manually-maintained list of special linking rules. -
--test-suitesto update Bikeshed’s database of test-suite information from the Shepherd system.
2.7. bikeshed refs
The refs command lets you search Bikeshed’s anchor database,
letting you see what sort of things it’s looking at when doing autolinking.
This can be very useful for debugging,
or just for a quick check of where something is defined.
It’s flags are similar to the attributes used on autolinks:
-
--text=FOOto specify the linktext you want to filter for -
--type=FOOto specify the link type -
--for=FOOto specify the for value -
--spec=FOOto specify the spec -
--status=footo specify the status -
--exactto turn off the variations that Bikeshed applies to some link texts (such as looking for "book" when you search for "books"), and just search for the exact text you specified
Any or all of these flags can be specified, and Bikeshed will display all the refs it can find matching the criteria.
2.8. bikeshed source
The source command applies various transformations to the source document itself,
rather than producing a separate output document.
Its options are described in §11 Source-File Processing: bikeshed source.
2.9. bikeshed issues-list
The issues-list command processes a plain-text document
in an "issues-list" format pioneered by the CSSWG
into an equivalent HTML version.
Relevant flags:
-
-toutputs a template issues-list file to stdout, making it easier to start a new document without having to reference an old one to remember the format. Use it likebikeshed issues-list -t > issues-19700101.txt.
After the command you can pass the input and output filenames.
As usual, one or both can be omitted:
if you omit the output,
it’ll write to a file with the same name as the input,
but a .html extension;
it you omit the input,
it will look in the current folder
for any files starting with "issues" and ending in ".txt",
and then extract the digits from those filenames
and select the one with the largest number.
If you name your file as suggested above,
with an ISO date,
it’ll correctly always choose the latest issues list.
Define the issues-list format.
The -t output is already more than enough to actually work with,
but it would still be good to describe it more fully.
3. Metadata
Crucial to the processor’s ability to automatically generate most of a spec’s boilerplate is a small metadata section, typically located at the top of a file.
A metadata block is just a <pre class='metadata'> element, with contents like:
Status: ED TR: http://www.w3.org/TR/css-variables/ ED: http://dev.w3.org/csswg/css-variables/ Shortname: css-variables Level: 1 Editor: Tab Atkins Jr., Google, http://xanthir.com/contact Editor: Daniel Glazman, Disruptive Innovations, [email protected] Abstract: This module introduces cascading variables as a new primitive value type that is accepted by all CSS properties, and custom properties for defining them.
The syntax of a metadata block is very simple - it’s a line-based format, with each line consisting of a key and a value, separated by a colon. Or if you’re adding multiple lines with the same key, you can just start the subsequent lines with whitespace to have it reuse the last-seen key.
Several keys are required information, and will cause the processor to flag an error if you omit them:
-
Title is the spec’s full title. This can alternately be specified by adding an
h1element as the first line of the spec. -
Status is the spec’s status. There are a few general abbreviations that can be used any group (or specs without a Group at all), and several that are restricted to particular groups.
Statuses usable by anyone
-
DREAM: "A Collection of Interesting Ideas"
-
LS: "Living Standard"
-
LS-COMMIT: "Commit Snapshot"
-
LS-BRANCH: "Branch Snapshot"
-
LD: "Living Document"
-
FINDING: "Finding"
Statuses usable by W3C groups
-
ED: "Editor’s Draft"
-
WD: "W3C Working Draft"
-
FPWD: "W3C First Public Working Draft"
-
LCWD: "W3C Last Call Working Draft"
-
CR: "W3C Candidate Recommendation"
-
PR: "W3C Proposed Recommendation"
-
REC: "W3C Recommendation"
-
PER: "W3C Proposed Edited Recommendation"
-
NOTE: "W3C Working Group Note"
-
MO: "W3C Member-only Draft"
-
UD: "Unofficial Proposal Draft"
-
CG-DRAFT: "Draft Community Group Report"
-
CG-FINAL: "Final Community Group Report"
Bikeshed has a listing of what Groups are associated with the W3C. If your Group isn’t on that list, it’ll complain when you try to use a W3C status. Please file a bug on Bikeshed to add your Group, and/or prefix your status like
Status: w3c/ED.Statuses usable by ISO groups
-
I: "Issue"
-
DR: "Defect Report"
-
D: "Draft Proposal"
-
P: "Published Proposal"
-
MEET: "Meeting Announcements"
-
RESP: "Records of Response"
-
MIN: "Minutes"
-
ER: "Editor’s Report"
-
SD: "Standing Document"
-
PWI: "Preliminary Work Item"
-
NP: "New Proposal"
-
NWIP: "New Work Item Proposal"
-
WD: "Working Draft"
-
CD: "Committee Draft"
-
FCD: "Final Committee Draft"
-
DIS: "Draft International Standard"
-
FDIS: "Final Draft International Standard"
-
PRF: "Proof of a new International Standard"
-
IS: "International Standard"
-
TR: "Technical Report"
-
DTR: "Draft Technical Report"
-
TS: "Technical Specification"
-
DTS: "Draft Technical Specification"
-
PAS: "Publicly Available Specification"
-
TTA: "Technology Trends Assessment"
-
IWA: "International Workshop Agreement"
-
COR: "Technical Corrigendum"
-
GUIDE: "Guidance to Technical Committees"
-
NP-AMD: "New Proposal Amendment"
-
AWI-AMD: "Approved new Work Item Amendment"
-
WD-AMD: "Working Draft Amendment"
-
CD-AMD: "Committe Draft Amendment"
-
PD-AMD: "Proposed Draft Amendment"
-
FPD-AMD: "Final Proposed Draft Amendment"
-
D-AMD: "Draft Amendment"
-
FD-AMD: "Final Draft Amendment"
-
PRF-AMD: "Proof Amendment"
-
AMD: "Amendment"
Bikeshed has a listing of what Groups are associated with ISO. If your Group isn’t on that list, it’ll complain when you try to use an ISO status. Please file a bug on Bikeshed to add your Group, and/or prefix your status like
Status: iso/ER.Statuses usable by the TC39 group
-
STAGE0
-
STAGE1
-
STAGE2
-
STAGE3
-
STAGE4
-
-
Shortname must contain the spec’s shortname, like "css-lists" or "css-backgrounds".
-
Level (or Revision, an alias) must contain the spec’s level as an integer.
-
Editor must contain an editor’s information. This has a special format of comma-separated clauses the first is required and must contain the editor’s name; all the rest are optional.
-
If editing a W3C document, your W3C ID (the number at the end of the url when you navigate to https://www.w3.org/users/myprofile) can be added as a
w3cid ####clause. -
Your affiliation (company you work for, etc), optionally followed by a link to their homepage, like
Example Company http://example.com. If your affiliation contains a comma, HTML-escape it (,). -
Your email address.
-
Your homepage.
All of the optional clauses can occur in any order, except that affiliation must occur before email or homepage.
Multiple Editor lines can be used to supply multiple editors.
-
-
Abstract must contain an abstract for the spec, a 1-2 sentence description of what the spec is about. Multiple Abstract lines can be used, representing multiple lines of content, as if you’d written those multiple lines directly into the document.
There are several additional optional keys:
-
TR must contain a link that points to the latest version on /TR.
-
Former Editor must contain a former editor’s information, in the same format as Editor.
-
Warning must contain either "Obsolete", "Not Ready", "New Version XXX", "Replaced by XXX", "Commit deadb33f http://example.com/url/to/deadb33f replaced by XXX", "Branch XXX http://example.com/url/to/XXX replaced by YYY", or "Custom", which triggers the appropriate warning message in the boilerplate.
If set to "Custom", the metadata keys Custom Warning Title and Custom Warning Text control what the warning contains.
-
Previous Version must contain a link that points to a previous (dated) version on /TR. You can specify this key more than once for multiple entries.
-
At Risk must contain an at-risk feature. You can specify this key more than once for multiple entries.
-
Group must contain the name of the group the spec is being generated for. This is used by the boilerplate generation to select the correct file. If omitted, it defaults to a generic set of boilerplate.
-
Status Text allows adding an additional customized sentence that can be used in the document status section.
-
Ignored Terms accepts a comma-separated list of terms and makes Bikeshed not emit warnings or errors when attempting to autolink those terms. Use this to quiet spurious preprocessor warnings caused by you inventing terms (for example, the Variables spec invents custom properties like 'var-foo'), or as a temporary patch when the spec you want to link to doesn’t set up its definitions correctly.
-
Date must contain a date in YYYY-MM-DD format, which is used instead of today’s date for all the date-related stuff in the spec.
-
Deadline is also a YYYY-MM-DD date, which is used for things like the LCWD Status section, to indicate deadlines.
-
Test Suite must contain a link to the test suite nightly cover page (like
http://test.csswg.org/suites/css3-flexbox/nightly-unstable). -
Mailing List must contain an email address to be used for mailing lists.
-
Mailing List Archives must contain a link to the list archives.
-
Issue Tracking indicates what and where you track issues, and will result in an "Issue Tracking" entry in your spec header. It must contain a comma-separated list of locations, each of which consists of the name of the location followed by the url.
Bikeshed will automatically add additional entries to this in some situations: if you use any inline issues, you’ll automatically get an "In Spec" annotation; if you develop from within a git repo with a GH remote, or have the Repository metadata set, you’ll automatically get a "GitHub" annotation.
You can turn off the spec-header entry entirely with
Boilerplate: feedback-header off, or just turn off the GitHub entry specifically withBoilerplate: repository-issue-tracking off. -
Issue Tracker Template specifies a url template used to point remote issues at your issue tracker of choice. It takes a url, with
{0}in the place where you want the remote identifier to go. -
Translation indicates a translation of the document. At minimum it consists of a language code (BCP47 format) and a url. Optionally, it can contain comma-separated
name [name-in-spec-language]andnative-name [name-in-translation-language], but if Bikeshed knows about that language, these will be filled in for you. (If Bikeshed doesn’t know about a given language, let me know what it’s name is in English and itself!) -
No Editor lets you omit the
Editormetadata without an error. It takes a boolish value. This shouldn’t generally be used; even if your organization doesn’t privilege editors in any way, putting the organization itself in theEditorfield meets the intent while still producing useful information for readers of the spec. -
Editor Term is a pair of comma-separated terms giving the singular and plural terms to refer to editors with, if you want something other than the default "Editor(s)".
-
Default Ref Status takes the values "current" or "snapshot", and selects which URL you want to default to for bibliography and autolinks entries that have both "current" and "snapshot" URLs. (You can also specify this per-biblio entry or per-autolink.)
-
Markup Shorthands lets you specify which categories of markup shorthands you want to use; for example, you can turn off CSS shorthands and reclaim use of single quotes in your spec. You can still link to things with explicit markup even if the shorthand is turned off. Its value is a comma-separated list of markup categories and boolish values, like
css no, biblio yes. The currently-recognized categories are:-
algorithm, covering the specialvarshorthand (the|foo|shorthand) -
biblio, covering the autolink shorthands for biblio links and section links (the[[foo]]shorthands) -
css, covering the autolink shorthands for CSS types -
dfn, covering the autolink shorthand for "dfn" type definitions -
idl, covering the autolink shorthands for WebIDL types (the{{foo}}shorthand) -
markdown, covering the various inline Markdown syntaxes (block-level Markdown is always supported) -
markup, covering the autolink shorthands for HTML/etc elements and attributes (the<{foo}>shorthand)
Everything but
markdowndefaults to "on". -
-
Text Macro lets you specify custom text macros, like
[TITLE]or[DATE], letting you fill in different text when building a spec in multiple ways. (This is mostly useful as a command-line option.) Each Text Macro line consists of a macro name, which must be uppercase and alphanumeric, followed by the text it will get replaced with. -
Work Status indicates the status of the document, in a way unrelated to the publication status of Status. It must be one of (completed, stable, testing, refining, revising, exploring, rewriting, abandoned), with those terms defined in Fantasai’s blog. This just sets the
[WORKSTATUS]text macro to the corresponding word, used in some of the boilerplates to pipe the metadata to scraping tools. -
Repository indicates the repository the spec is being tracked in. You can specify a url followed by a "short name" for it, and it populates the
[REPOSITORY]and[REPOSITORYURL]text macros accordingly. If you are using GitHub, you can just specifyusername/repo, and Bikeshed will infer the rest for you. If you’re developing from within a GitHub repo, you don’t need to specify this at all, as Bikeshed will figure it out automatically! (That said, if you’re working in a fork, you should still specify the main repo’s information here, or else the spec will point to your fork instead.)If using GitHub, this metadata causes Bikeshed to automatically add a "GitHub" annotation to the Issue Tracking entry in your spec header. You can turn this off with
Boilerplate: repository-issue-tracking off. -
Inline Github Issues tells Bikeshed whether to fetch the text of GitHub issues and inline them into the document, or not. It takes a boolish value, or the values "full" or "titles". If it’s true or "full", any remote issues of the form
user/repo#issuenumberwill have their contents replaced by the contents of the corresponding issue from GitHub; if it’s "titles", they’ll have their contents replaced by just the title of the remote issue (so a large, well-written initial issue post doesn’t derail a spec). If your Repository is set up to a GitHub repo, remote issues with just an issue number will also be expanded to the corresponding issue from your repository. -
Inline Github Issue Titles fetches remote issues with the same mechanism as Inline Github Issues but output only the title instead of title and body of the issue.
-
Opaque Elements and Block Elements are a comma-separated list of custom element names, to help control Bikeshed’s parsing and serialization. By default, custom elements are treated as inline; marking an element as "opaque" makes it like
pre, so shorthands and Markdown aren’t processed in it, and it’s serialized precisely as entered; marking an element as "block" makes it interrupt paragraphs when it starts a line, and causes the pretty-printer to serialize it in a block-like way. -
Note Class, Issue Class, Assertion Class, and Advisement Class specify the class name given to paragraphs using the note/issue/advisement markup shorthand. They default to "note", "issue", and "advisement".
-
Translate IDs maps Bikeshed-generated IDs to manually-specified IDs, for cases where you need to manually specify an ID but it’s generated by Bikeshed in a hard-to-override way (like IDL blocks). It takes a comma separated list of Bikeshed IDs and new IDs.
-
Default Highlight specifies the default highlighting language. Every
pre,xmp, andcodewill automatically be highlighted according to the specified language, unless they or an ancestor specifies a differenthighlight=fooornohighlightattribute overriding it. -
Toggle Diffs includes a 'Hide deleted text' button to toggle hiding
delelements. -
Boilerplate toggles the generation of individual boilerplate sections. Its value is a comma-separated list of section name and boolish value, e.g.
Boilerplate: issues-index noto disable the list of issues. -
Complain About indicates what nits you’d like Bikeshed to complain about, that are normally too noisy to be turned on by default. Its value is a boolish list like Markup Shorthands. Accepted values are:
-
missing-example-ids- complains about examples without a manually-specified ID. (Examples auto-generate an ID based on their contents otherwise, which might not be stable over time.) -
broken-links- checks all the external links in the document, and verifies that they result in a 200 response code. Might take a while if your document links out a lot!
-
-
Infer CSS Dfns is a boolish that specifies whether Bikeshed should try to "infer" what type a
dfnis by looking at the text, using CSS-biased heuristics. (In other words, this’ll only auto-detect certain CSS types.) Defaults to off. -
Assume Explicit For is a boolish that specifies whether an omitted
forattribute on an autolink should implyfor="/"(that is, selecting a definition without aforvalue), or just not express aforrequirement at all (that is, selecting a definition without caring about what itsforvalue is). Truthy values set the former, falsey set the latter. Defaults to off.Note: Turning this on is a better match for some people’s mental models, but it requires you to specify more
forvalues on your autolinks even when it’s not necessary to disambiguate things, so it’s off by default. -
Max ToC Depth specifies the maximum depth you want the ToC to generate to. It can be the value "none", meaning generate the ToC normally, or an integer between 1 and 5. It defaults to "none".
-
Include Can I Use Panels is a boolish that specifies whether to include Can I Use usage-data panels or not. If it’s turned on,
dfnelements can take acaniuse="featureID"attribute, where thefeatureIDis the value specified in the url likehttp://caniuse.com/#feat=FEATUREIDHERE, and the panel will be positioned to line up with thatdfn. -
Can I Use URL automatically informs you when/if Can I Use starts tracking new features from your spec, so you don’t have to check that yourself. It takes a single URL prefix, and can be specified multiple times to provide multiple URLs. These URLs are checked against the Can I Use data, and if there are any Can I Use features whose URL includes one of the specified URLs as a prefix, and the feature isn’t already specified somewhere in your spec, it will log a warning for you.
-
Custom Warning Title specifies the title of a "custom" warning, requested via
Warning: custommetadata. -
Custom Warning Text specifies the body of a "custom" warning. Like Abstract, it accepts multiple lines, and is parsed as Markdown (as if you’d written them directly into the document).
Note: A boolish value is a string representing a boolean value (true or false). The string "yes", "on", "true", and "y" all represent true values, while the strings "no", "off", "false", and "n" all represent false values.
You can also provide custom keys with whatever values you want,
by prefixing the key with !,
like !Issue Tracking: in spec.
Any custom keys are collected together and formatted as entries in the spec’s boilerplate header dl.
Specifying a custom key multiple times will put all the values as dds under a single dt for the key.
Some of the metadata keys are deprecated; you shouldn’t use them, but just in case you run into them in the wild, they’re documented here for understanding. Each one recommends what you should be using instead.
-
Use <i> Autolinks turns on legacy support for using
ielements as "dfn" autolinks. It takes a boolish value.Instead of using this, just use the
aelement to autolink, as usual. -
Link Defaults lets you specify a default spec for particular autolinks to link to. The value is a comma-separated list of entries, where each entry is a versioned spec shortname, followed by a parenthesized link type, followed by a "/"-separated list of link phrases. For example,
Link Defaults: html (dfn) allowed to show a popup/in parallel.Instead of using this, use a
<pre class=link-defaults>block, as the error message suggests when this is necessary. -
Ignored Vars accepts a comma-separated list of variable names, and makes Bikeshed not emit warnings or errors about them being used only once in the document/algorithm.
Instead of using this, put an
ignoreattribute on thevarin question.
3.1. Default Metadata
To specify default metadata for all specs generated for a given group and/or spec status,
add an appropriate "default.include" file to the include/ folder.
This file must be a JSON file,
with the keys and values all strings matching the above descriptions.
Here’s an example file:
{ "Mailing List": "[email protected]", "Mailing List Archives": "http://lists.w3.org/Archives/Public/www-style/" }
3.2. Overriding Metadata From The Command Line
If you want to generate multiple versions of a spec from the same source (such as a primary spec, plus some snapshots), you can override the metadata from the command line to generate the alternate forms.
For any metadata key defined above,
just pass it as a --md-foo=bar command-line argument.
For example, to override the Status metadata,
run bikeshed spec --md-status=ED.
(If the metadata name has spaces in it, use dashes to separate the words instead.)
3.2.1. Known Issues
-
You can’t override the
Use <i> Autolinksstatus, because you can’t input the<>characters. I don’t intend to fix this, as you shouldn’t be specifying this in the first place. -
You can’t supply custom metadata keys (ones with a
!prefix). If you want to do this, let me know, and I’ll work on it. -
Passing values with spaces in them is tricky. This is an issue with the argparse library. The only way around it is to specify both of the positional arguments (the input and output filenames), then put the offending argument after them.
4. Markup Shortcuts
Bikeshed’s source format is roughly HTML, but it allows you to omit or shorten several verbose/annoying parts of the language, reducing the amount of format noise in the spec source, making it easier to read and write.
4.1. Markdown
Bikeshed currently recognizes a subset of Markdown:
-
paragraphs
-
lists
-
headings
-
horizontal rules
-
fenced code blocks
-
emphasis and strong span elements
-
inline links, with optional title
It also recognizes definition lists, with the following format:
Here’s the dl syntax: : key :: val : key 1 : key 2 :: more vals
For all three list formats, on the rare occasions you need to add a class or attribute to the list, you can wrap it in the appropriate list container, like:
<ol class=foo> 1. first 2. second </ol>
Bikeshed will use the container you provided, rather than generating a fresh one like it does by default.
It supports adding IDs to headings, via the Markdown Extra syntax:
Header 1 {#header1}
========
### Header 2 ### {#header2}
More of Markdown will be supported in the future, as I get closer to adhering to the CommonMark specification.
4.2. Notes, Issues, Examples, Advisements
The Markdown processor specially recognizes paragraphs starting with
"Issue: ",
"Advisement: ",
"Assertion: ",
"Note: ",
or "Note, ",
and will add a matching class to the paragraph automatically.
These classes default to .issue, .advisement, .assertion, and .note,
but can be customized with the metadatas Issue Class, Advisement Class, Assertion Class, and Note Class.
(However, the default classes receive styling from the default stylesheet,
so make sure you provide your own styling if you change them.)
The default styling of these blocks includes a generated-content "header"
containing the word "NOTE:", etc.
If you’d like to provide your own custom header,
write out the container element yourself
(rather than using the Markdown shorthand,
just create any element with the appropriate class),
and add a heading="YOUR TEXT HERE" attribute to the container.
It will automatically have "NOTE: "/etc prepended to it.
This also works on elements with the .example class.
(This is used by §4.11 Remote Issues to put the GitHub issue title on the issue containers.)
4.3. Typography Fixes
Bikeshed will automatically handle a few typographic niceties for you, ones that it can reliably detect:
-
Possessive apostophes, and most contraction apostrophes, are automatically turned into curly right single quotes (
’). -
Ending a line with
--will turn it into an em dash (—) and pull the following line upwards so there’s no space between the surrounding words and the dash.
4.4. Autolink Shortcuts
There are several shortcuts for writing autolinks of particular types, so you don’t have to write the a element yourself:
-
'foo'(apostophes/straight quotes) is an autolink to a property or descriptor named "foo" -
''foo''(double apostrophes) is an autolink to any of the CSS definition types except property and descriptor -
<<foo>>is an autolink to a type/production named "<foo>" -
<<'foo'>>is an autolink to the the property or descriptor named "foo" (used in grammars, where you need<foo>for non-terminals) -
<<foo()>>is an autolink to the function named "foo" (same) -
<<@foo>>is an autolink to the at-rule named "@foo" (same) -
{{Foo}}is an autolink to an IDL term named "Foo". (Accepts interfaces, attributes, methods, etc) -
<{Foo}>is an autolink to an element named "Foo". -
|foo|is a variable reference (<var>). -
[[foo]]is an autolink to a bibliography entry named "foo", and auto-generates an informative reference in the biblio section. Add a leading exclamation point to the value, like[[!foo]]for a normative reference. -
[[#foo]]is an autolink to the heading in the same document with that ID. This generates appropriate reference text in its place, like "§5.3 Baseline Self-Alignment" -
<i>elements can be enabled as autolinks as well, usingUse <i> Autolinks: yesmetadata. (The CSSWG has this enabled by default.)
If using the ''foo'', <<'descriptor'>>, {{Foo}}, or <{element}> shortcuts,
you can specify the for="" attribute in the shortcut as well
by writing the for value first, then a slash, then the value.
For example, ''width/auto'' specifically refers to the auto value for the width property,
which is much shorter than writing out <a value for=width>auto</a>.
For the {{foo}} shortcut,
you can also specify exactly which type of IDL link it is,
in case of ambiguity,
by appending !! and the type,
like {{family!!argument}},
which is equivalent to <a argument><code>family</code></a>
Remember that if you need to write out the a tag explicitly,
you can add the type as a boolean attribute.
4.5. var and Algorithms
The var element (or its shorthand equivalent, |foo|) is often used to mark up "arguments" to a prose algorithm.
Bikeshed explicitly recognizes this,
and has several features related to this.
Algorithms can be explicitly indicated in your markup
by putting the algorithm="to foo a bar" attribute on a container element
or a heading.
All vars within an algorithm are "scoped" to that algorithm.
Generally, vars are used at least twice in an algorithm:
once to define them,
and at least once to actually use them for something.
If you use a var only once,
there’s a good chance it’s actually a typo.
Bikeshed will emit a warning if it finds any vars used only once in an algorithm.
If this singular usage is correct,
you can instruct Bikeshed to ignore the error by adding an ignore attribute to the var itself.
(There’s no way to do this with the |foo| syntax;
you have to convert it back to an actual var element.)
4.6. pre whitespace stripping
Using a pre element in HTML is unsatisfying,
because it forces you to break your indentation strategy,
pulling the content back to the margin edge
(or else employing silly hacks with comments and explicit newlines).
The preprocessor fixes this.
Whenever a pre element is encountered,
the processor records how much whitespace precedes the first line,
and then strips that much whitespace from it and all following lines.
Additionally, if the closing </pre> is on its own line,
the processor automatically pulls it up onto the end of the previous line,
so there’s no final blank line in the content.
In other words, you can now write:
<div class='example'> <p> An example: <pre> <ul> <li>one <li>two </ul> </pre> </div>
The preprocessor will automatically convert it into:
<div class='example'> <p> An example: <pre> <ul> <li>one <li>two </ul></pre> </div>
4.7. Syntax Highlighting
You can also syntax-highlight code blocks.
Just add either a highlight="foo" attribute
or a lang-foo class to the element,
and the element will automatically be syntax-highlighted according to the "foo" language rules.
The syntax highlighter uses Pygments, which supports a large set of languages. See http://pygments.org/docs/lexers/ for the full list. (Use one of the "short names" of the language for the "foo" value.)
Note: If you use "html", script and style elements are automatically highlighted with JS and CSS rules.
4.8. Property/descriptor/element definition table expansion
Propdef tables are rather large, even when correctly formatted.
Instead, you can write the table in a simple text format similar to the spec’s metadata block,
and let the processor automatically generate a table from it:
<pre class='propdef'> Name: flex-basis Value: content | <<'width'>> Initial: auto Applies to: <a>flex items</a> Inherited: no Computed value: as specified, with lengths made absolute Percentages: relative to the <a>flex container’s</a> inner <a>main size</a> Media: visual Animation type: length </pre>
The data block is parsed as a series of lines, with each line composed of one of the propdef headings, a colon, then the value.
The property name will automatically be wrapped in a dfn element.
Within the Values line, things that look like grammar nonterminals (anything like <foo>) will be automatically escaped and wrapped in var elements.
This also works for descdef tables, describing the syntax of descriptors. When writing a descdef table, you should additionally add a "For" line containing the name of the at-rule the descriptor is for.
If you’re defining a partial propdef or descdef
(for example, just defining a few new values for an existing property),
you can indicate this by adding a "partial" class to the pre.
(This will prevent Bikeshed from complaining about lots of missing propdef/descdef lines.)
The format of an elementdef table is a little different. It can contain the following lines:
-
Name - the element name(s)
-
Categories - what "categories" the element is classified in, such as "flow content" or "graphics element". These must be defined terms, as Bikeshed will attempt to link them.
-
Contexts - what contexts the element can be used in
-
Content Model - what kind of elements and other nodes can validly appear inside the element
-
Attributes - what attributes are defined for the element. These must be defined (as
element-attrdefinitions), as Bikeshed will attempt to link to them. -
Attribute Groups - optional. If some attributes commonly appear on lots of elements, you can classify them into groups and list them here. The group name must be defined as a
dfntype definition, with the attributes in the group defined aselement-attrdefinitions with aforvalue of the group name. Bikeshed will expand the group into a<details>element for you and automatically link the attributes. -
DOM Interfaces - list the IDL interfaces that correspond to the elements defined in the block. These must be defined (as
interfacedefinitions), as Bikeshed will attempt to link to them.
4.9. Automatic ID Generation
If any heading, issue, or dfn element doesn’t have an id attribute,
one will be automatically generated by the processor,
to ensure it’s usable as a link target.
Heading IDs are generated directly from the text contents of the element, cleaning up the characters to be a valid id. This often isn’t the best for complex heading texts, so it’s not recommended to rely on this. (Bikeshed will warn you that it’s generating IDs, and suggest you supply one manually.)
If a heading changed significantly,
so that you want to change the ID,
but you want links to the old heading ID to still work,
put the old ID in an oldids="" attribute on the heading element.
If there are multiple, comma-separate them.
Issues (elements with class="issue") will generate IDs of the form "issue-###",
where "###" is substring of a hash of the issue’s contents.
This means that an issue’s ID will be stable against changes elsewhere in the document,
including adding or removing issues above it in the source,
but will change if you change the contents of the issue.
Definition IDs are also generated directly from the text contents of the element. Most definitions additionally get a prefix, such as "propdef-", to avoid clashes with other definitions.
If an automatically-generated ID would collide with any other ID, it’s automatically de-duped by appending a number to the end. This isn’t very pretty, so if you want to avoid it, supply an ID yourself.
Bikeshed recognizes a fake element named <assert> for marking "assertions" that tests can refer to.
In the generated output, this is converted to a <span> with a unique ID generated from its contents,
like issues (described above).
This ensures that you have a unique ID that won’t change arbitrarily,
but will change when the contents of the assertion change,
making it easier to tell when a test might no longer be testing the assertion it points to
(because it’s no longer pointing to a valid target at all!).
4.10. Automatic Self-Link Generation
Giving IDs to important things in your document, like headings and definitions, is great, but of little use if people don’t know they can link to them. Bikeshed will automatically generate a "self-link" in the margin next to certain linkable elements which just links to the element, so people can click on the link and then just copy the URL from their address bar to get a link straight to what they care about.
Self-links are currently auto-generated for headings, definitions, and issues,
and notes, examples, <li>s, and <dt>s that have been given IDs.
4.11. Remote Issues
As defined earlier, you can start a paragraph with Issue: to cause Bikeshed to automatically format it as an inline issue paragraph.
You can also refer to remote issues, which are tracked in some other issue tracker.
To do so, instead start your paragraph with Issue(###):,
where the ### is some identifying value for the issue.
If the identifying value is of the form user/repo#number,
Bikeshed assumes you are referring to GitHub repository,
and points the issue at the corresponding issue.
If you have Repository set up to point to a GitHub repository (or it was auto-detected as such, because you’re working on the spec from within one), then a numeric identifying value is assumed to be an issue number for your repository.
Otherwise, you need to tell Bikeshed how to convert the identifying value into a remote issue link.
Specify a format string in the Issue Tracker Template metadata,
with a {0} in the place where the identifying value should go.
Bikeshed will then point the issue at the generated url.
4.12. Including Other Files
Sometimes a spec is too large to easily work with in one file. Sometimes there’s lots of repetitive markup that only changes in a few standard ways. For whatever reason, Bikeshed has the ability to include additional files directly into your spec with a <pre class=include> block:
<pre class=include> path: relative/to/cwd </pre>
Unless path is absolute, bikeshed searches for the file relative to the
current working directory, i.e. the directory in which bikeshed was launched.
The included document is parsed just like if it were written in locally, except that metadata blocks aren’t processed. (For various reasons, they have to be parsed before any other processing occurs). This means that the include file can use markdown, data blocks of various kinds (<pre class=anchors>, <pre class=railroad-diagram>, etc), and both provide definitions for the outer document and refer to ones defined by the outer document.
If you’re including a block of repetitive markup multiple times, and want to vary how it’s displayed, you can pass additional "local" text macros in the block, which are valid only inside the included file:
<pre class=include> path: template.md macros: foo: bar baz: qux qux qux </pre>
With the above code, you can use [FOO] and [BAZ] macros inside the include file,
and they’ll be substituted with "bar" and "qux qux qux", respectively.
(Remember that you can mark text macros as optional by appending a ?, like [FOO?],
in which case they’ll be replaced with the empty string if Bikeshed can’t find a definition.)
5. Definitions
Defining a term is as easy as wrapping a dfn element around it.
Most of the time, this is all you’ll need to do -
the definition automatically gains an id,
and is usually automatically exposed as an autolink target for local and cross-spec autolinks.
Autolinking is a special mechanism in the processor to let you link terms to their definitions without having to explicitly provide a url.
Instead, the text of the link is matched against the text of the definitions,
and if a match is found,
the link’s href is set up to connect the two.
5.1. Conjugating/Pluralizing/etc the Linking Text
Bikeshed can automatically handle a wide range of English conjugations and pluralizations.
For example, if you define the term "snap",
you can link to it with "snapping" or "snapped"
without having to manually add those variations to your dfn manually.
As such, it’s best to define your term in the "base" form,
singular and present tense.
Use lt='...' if necessary to set up the correct "base" linking text,
if your visible text needs to be in a conjugated form due to the surrounding text.
These variations only work for the last word in a phrase.
If you have a longer phrase where it’s a middle word that conjugates differently,
you do still have to manually handle that,
either by defining multiple linking texts on the dfn,
or by manually specifying the linking text on the a.
5.2. Changing the Linking Text
Sometimes, the text of the definition isn’t exactly what you want it to be linked by,
or you may want it to be linkable with more than one phrase.
For example, an algorithm named "Check if three characters would start an identifier"
may also want to be linkable from the phrase "starts with an identifier".
To alter the linking text, simply add an lt attribute (for "Linking Text") to the definition;
the linking text is used instead of the text content.
You can separate multiple linking phrases by separating them with the pipe "|" character.
5.3. Defining Extra-Short "Local" Linking Texts
Sometimes you want to use an extra-short version of a term for within a spec,
but don’t want to confuse things by exporting it globally.
To achieve this, add a local-lt attribute with the terms you want to be only usable within the spec;
the syntax is identical to that of the lt attribute, described above.
Using local linking text does not disturb the normal linking-text process;
that still takes from either the element text or the lt attribute,
as normal.
5.4. Definition Types
All definitions have a definition type. This allows for "namespacing" of the linking text, so you can define, for example, both a property and a term with the same linking text, such as "direction" or "color".
There are several types for CSS values:
-
property
-
descriptor (the things inside at-rules like @font-face)
-
value (any value that goes inside of a property, at-rule, etc.)
-
type (an abstract type for CSS grammars, like
<length>or<image>) -
at-rule
-
function (like counter() or linear-gradient())
-
selector
There are additional types for WebIDL definitions:
-
interface
-
constructor
-
method
-
argument
-
attribute
-
callback
-
dictionary
-
dict-member
-
enum
-
enum-value
-
exception (for new DOMException names)
-
const
-
typedef
-
stringifier
-
serializer
-
iterator
-
maplike
-
setlike
-
extended-attribute (things like
[EnforceRange])
And for HTML/SVG/etc element definitions:
-
element
-
element-state (a spec concept, like
inputbeing in the "password state") -
element-attr
-
attr-value
A special type for URL schemes, like "http" or "blob":
-
scheme
A special type for HTTP headers:
-
http-header
A special type just for definitions of operators used in grammar definitions,
like || and similar:
-
grammar
And finally, some categories for "English" terms:
-
abstract-op (for "English-language algorithms")
-
dfn (for general terms and phrases, and a catch-all for anything else)
The processor will attempt to infer your definition type from the context and text content of the definition:
-
Is it inside a propdef, descdef, or elementdef block? Then it’s a property, descriptor, or element.
-
Is it inside an idl block (<pre class='idl'>)? Then it’s an one of the IDL types, inferred by parsing the IDL.
-
Does it start with an
@? Then it’s an at-rule. -
Is it surrounded by
<>? Then it’s a type. -
Does it start with a
:? Then it’s a selector. -
Does it end with
()? Then it’s a function. -
Is it surrounded by double single quotes in the source, like
''foo''? Then it’s a value. -
Otherwise, it’s a dfn.
(This auto-detection is obviously skewed towards CSS types; Bikeshed started as a CSS spec preprocessor, and the CSS types are easier to auto-detect syntactically than anything else.)
Note that this auto-detection is a last-resort operation. There are methods (defined below) to explicitly indicate what type a definition is, and those win over the auto-detection.
If your value doesn’t fit one of these categories, you’ll have to tag it manually. Just add the type as a boolean attribute to the definition, like
attribute DOMString <dfn attribute for=Foo>name</dfn>;
Alternately, if you’ve got several definitions of the same type that share some container element (such as a <pre> or <dl>),
just add a dfn-type="type-goes-here" attribute to the container.
Anything which isn’t explicitly tagged otherwise will take that type by default.
(There are more methods to determine definition type, but they’re only meant for legacy content, and so are not documented here.)
5.5. Namespacing a Definition
Some types of definitions are defined relative to a higher construct, such as values for a particularly property, or attributes of a particular IDL interface. This is useful, as it means these names don’t have to be globally unique, but that means your autolinks may have a hard time telling which name you intend to link to.
To fix this, the processor enforces that some types of definitions must define what they are for.
This is specified with a for attribute on the definition.
Specifically:
-
"attribute", "constructor", "method", "const", "event", "serializer", "stringifier", and "iterator" definitions must define what interface they’re relative to.
-
"argument" definitions must define what method or constructor they’re relative to.
-
"dict-member" definitions must define what dictionary they’re relative to.
-
"except-field" and "exception-code" definitions must define what exception they’re relative to.
-
"enum-value" definitions must define what enum they’re relative to
-
"element-attr" and "element-state" definitions must define what element they’re relative to.
-
"attr-value" definitions must define what element and attribute they’re relative to.
-
"descriptor" definitions must define what at-rule they’re relative to. (This happens automatically if you add a "For" line to the descdef table.)
-
"value" definitions must define what property, descriptor, at-rule, type, selector, or function they’re relative to. If a value definition is relative to a descriptor, the value must be of the form "@foo/bar", where "@foo" is the at-rule the "bar" descriptor is relative to.
Just like with the definition type, you can instead declare what several definitions are for by putting an attribute on a container.
In this case, just add dfn-for to the container.
This is especially useful for property/descriptor values, as they’re usually defined in a dl,
or IDL definitions, as you can just put a dfn-for on the <pre class='idl'>.
If a single definition is "for" multiple things, you can provide a comma-separated list of values in the attribute.
5.6. Exporting Definitions
Most definitions are automatically "exported", which means they’re made available for other specs to autolink to. The only exception is "dfn" type definitions, which aren’t exported by default.
To force a link to be exported, add an export boolean attribute to it.
To force a link not to be exported, add a noexport boolean attribute instead.
Like the other attributes, you can instead add this to a container to have it be a default for the definitions inside.
5.7. Providing Custom Definitions
If you want to link to dfns in specs that aren’t yet part of the autolinking database,
you can provide your own definition data that Bikeshed can use.
Within a <pre class='anchors'> element,
define the anchors you need in InfoTree format,
with the following keys:
-
text - the linking text for the definition. (Exactly 1 required.)
-
type - the definition’s type (dfn, interface, etc) (Exactly 1 required.)
-
urlPrefix and/or url - define the anchor’s url, as described below. (At least one of
urlPrefixorurlmust be specified. 0+urlPrefixentries allowed, 0 or 1urlentries allowed.) -
for - what the definition is for. (Any number allowed, including 0.)
-
spec - Which spec the definition comes from. (optional)
To generate the url for the anchor,
first all of the urlPrefix entries are concatenated.
If a url is provided,
it’s appended to the prefixes;
otherwise, the text is url-ified and appended.
(Lowercased, spaces converted to dashes, non-alphanumeric characters dropped.)
If neither urlPrefix nor url had a "#" character in them,
one is inserted between them.
The spec attribute is used only for index generation, and has no effect on URL generation.
Example:
<!--line count correction 4--> <a>ascii whitespace</a> links now!
Alternately, this data can be provided in a file named anchors.bsdata,
in the same folder as the spec source, but this prevents you from using the web service.
5.8. Definitions data model
Bikeshed’s most important feature is its powerful cross-spec autolinking. This is possible due to each definition being annotated with a rich set of metadata, which is then exposed via custom attributes and picked up by specialized scrapers (such as Shepherd) that then compile a definition database that Bikeshed relies on.
If you’re writing a spec processor or related tool and would like to interoperate with the Bikeshed ecosystem, here’s the full definition data model and how to properly expose it.
-
The defining element MUST be a
dfnorh2...h6. No other element is recognized as defining a term. -
The element MUST have an
idattribute. -
The linking text defaults to the text content of the
dfn/heading. If the desired text content isn’t suitable for linking text, or you wish to provide multiple linking texts, a [ltattribute](#changing-lt) containing one or more pipe-separated linking texts will override the text content. See also §5.3 Defining Extra-Short "Local" Linking Texts -
data-dfn-typeMUST be provided, and set one of the accepted values. (Thedfnelement, specifically, actually allows this to be omitted, and defaults to the "dfn" type. But headings require a type, anddfns are clearer with it specified.) -
Either
data-exportordata-noexportMAY be provided (both boolean attributes). If neither is provided, "dfn" type definitions default to noexport, while all others default to export. Unexported definitions aren’t linkable by default. -
Several types of definitions are namespaced to another construct; for example, attribute names are namespaced to an interface. These definitions MUST contain a
data-dfn-forattribute, containing a comma-separated list of one or more definitions they’re namespaced to.
If you have written a web spec and it conforms to this definition syntax, contact the project maintainer and ask them to register your spec in Shepherd, so its definitions will be available to everyone else.
6. Autolinking
The processor supports "autolinks" for easy linking to terms without having to fiddle around with urls. Instead, just match up the text of the link to the text of the definition!
In its most basic form, autolinks are just a elements without href attributes.
The processor takes this as a signal that it should attempt to automatically determine the link target.
It compares the text content of the link to the text content of all the definitions in the page or in the cross-ref data,
and if it finds a match,
automatically sets the href appropriately to point at the relevant definition.
Like definitions, you can override the linking text by setting a lt attribute.
Unlike definitions, you can’t separate multiple linking phrases by the bar "|" character,
as that doesn’t make sense for links.
Setting an empty lt attribute turns off autolinking entirely, if for whatever reason you need to do so.
There are several additional autolink shorthands for writing an autolink.
The Dfn variety (controlled by Markup Shorthands: dfn yes):
-
[=foo=]is an autolink to the "dfn" type definition "foo".
The CSS varieties (controlled by Markup Shorthands: css yes):
-
'foo'(apostophes/straight quotes) is an autolink to a property or descriptor named "foo". If there is both a property and a descriptor of a given name, this defaults to linking to the property if used in its bare ('foo') form. -
''foo''(double apostrophes) is an autolink to any of the CSS definition types except property and descriptor -
<<foo>>is an autolink to a type/production named "<foo>" -
<<'foo'>>is an autolink to the the property or descriptor named "foo" (used in grammars, where you need<foo>for non-terminals). -
<<foo()>>is an autolink to the function named "foo" (used in grammars) -
<<@foo>>is an autolink to the at-rule named "@foo" (used in grammars)
The IDL variety (controlled by Markup Shorthands: idl yes):
-
{{foo}}or{{foo()}}is an autolink to one of the IDL types (interface, method, dictionary, etc) for the term "foo".
The markup (HTML/etc) varieties (controlled by Markup Shorthands: markup yes):
-
<{element}>is an autolink to the element named "element". -
<{element/attribute}>is an autolink to the attribute or element-state named "attribute" for the element "element". -
<{element/attribute/attribute value}>is an autolink to the value "attribute value" of an attribute or element-state named "attribute" for the element "element".
The bibliography/spec varieties (controlled by Markup Shorthands: biblio yes):
-
[[foo]]is an autolink to a bibliography entry named "foo", and auto-generates an informative reference in the biblio section. Add a leading exclamation point to the value, like[[!foo]], for a normative reference. If both a "current" and "dated" bibliography entry exists for that entry, Bikeshed will prefer the "current" one by default (but this can be controlled by the Default Ref Status metadata). To explicitly link to one or the other, specify it after the name, like[[foo current]]. -
[[#foo]]is an autolink to a heading in the same document with the given ID. (See §6.5 Section Links for more detail.) -
[[foo#bar]]is an autolink to the heading with ID "bar" in the spec whose leveled shortname is "foo". (This only works for specs known to Bikeshed’s autolinking database, which is distinct from its bibliography database.) If linking into a multi-page spec and the desired ID shows up on multiple pages, write it like[[spec/page#id]], wherepageis the filename (without extension) of the page being linked to. Or to link just to the page itself, rather than any particular heading, write[[spec/page]].
Any of the above shorthands (besides the biblio varieties) can, if they’re specifying a link type that can have a for value, specify that explicitly by prepending the for value and separating it with a /, like the following to indicate that you want the "bar" attribute of the "Foo" interface (rather than of some other interface):
{{Foo/bar}}
If the for value is itself of a type that can have a for value, you can prepend more specifiers if necessary, like ''@foo/bar/baz'' to refer to the "baz" value for the "bar" descriptor of the "@foo" at-rule or <{ol/type/A}> to refer to the "A" attribute value for the "type" attribute of the "ol" element.
If you need to explicitly refer to the definition instance without a for value
(which would be written as <a for="/">foo</a> in normal markup),
just use the slash with nothing preceding it,
like [=/foo=]. Note, this does not apply to types that require a for value.
Any of the above shorthands (besides the biblio varieties) that encompass multiple types can have their type specified explicitly, by appending the type and separating it with a !!, like the following to indicate that you want the IDL attribute named "bar", rather than the dictionary member of the same name:
{{bar!!attribute}}
Any of the above shorthands (including the biblio varieties) can override their default display text (the term you’re autolinking) with some other explicitly specified text, by appending the new text and separating it with a |, like the following to indicate you want to link to the "do foo" term but display "when foo is done":
[=do foo|when foo is done=]
If both specifying the type and overriding the display text, put the type-specifier first then the desired display text, like:
{{bar!!attribute|the bar attribute}}
6.1. Link Types
Links have the same types as definitions, with a few additional "union" types that are used by the shortcut forms. While you shouldn’t specify them explicitly, they’ll show up in error messages sometimes, so here’s a list of them:
-
"propdesc" - used by the
'foo'shorthand. A union of "property" and "descriptor". -
"functionish" - used by the
''foo()''shorthand for things that look like functions. A union of "function", "method", "constructor", and "stringifier". -
"maybe" - used by the rest of the
''foo''shorthand values. A union of "dfn" and all the CSS types except "property" and "descriptor". For legacy reasons, this link type has the additional magic that it doesn’t flag an error if it can’t find any matches, because it’s also used to annotate inline CSS code fragments. -
"idl" - used by the
{{foo}}shorthand. A union of all the IDL types. -
"idl-name" - used by the IDL auto-parser. A union of all the IDL types that can declare IDL argument types, like "interface", "enum", or "dictionary".
-
"element-sub" - used by the
<{foo/bar}>shorthand. A union of "element-attr" and "element-state".
When you actually run the processor, you may get errors about there being too many possible references to choose from. The processor will continue to run anyway, but its default choice might be the wrong definition. There are three things you might have to do to fix these:
-
Specify the type explicitly, if the link isn’t being processed as the correct type. Like definitions, this can be done by just adding the type as a boolean attribute on the link, or by adding a
link-forattribute to a container. If the link is using shorthand syntax, you can use the!!typesuffix to specify the type. -
If the link type corresponds to one of the definition types that needs
forto be specified, you may need to specifyforon the link as well to narrow down which definition you’re referring to. For example, many CSS properties define an "auto" value; to link to the "auto" value of the 'width' property in particular, specify<a value for=width>auto</a>, or the shorthand syntax''width/auto''. To refer to a value of a descriptor, you can be completely explicit and specify the at-rule as well, like<a value for='@counter-style/system'>numeric</a>, but you’re allowed to omit the at-rule if there are no other properties or descriptors with the same name, like''system/numeric''. This might trigger errors in the future if a conflicting term gets added later, but it keeps your links shorter for now.Again, you can specify a
link-forattribute on a container to default it for all the autolinks inside the container. Alternately, you can specifylink-for-hinton a container, which’ll use the hint as the for value if possible (if doing so wouldn’t eliminate all the possible links). This is useful if some container has a bunch of links for a given property, say, but some of the links are to other things entirely; usinglink-formeans you have to manually specify the other links aren’t for anything, butlink-for-hintis more "do what I mean". -
If multiple specs define the same term, you may need to declare which spec you’re referring to. (The processor is smart enough to automatically figure out which one you probably want in many cases.) Just add a
specattribute with the spec’s shortname to either the link or a container. This can also be specified document-wide, as described in §6.3 Configuring Linking Defaults. (There is no shorthand syntax for specifying this; if you need to add this to a shorthand autolink, you must first convert it into an explicitaelement.)
As a final note, the autolinking algorithm will link differently based on whether the spec being processed is a "current" (up-to-date) or "dated" (snapshot) draft. If "current" (ED, UD, etc.), it’ll prefer to link to other current drafts, and will only link to "dated" if no "current" version of that spec exists. (If a definition only exists in the "dated" draft but not the "current" draft, that almost certainly means it’s been deleted since the "dated" draft was last published, and thus shouldn’t be linked to.) On the other hand, "official" (WD, CR, etc.) specs will preferentially link to other official specs. A future version of the processor will likely enforce the W3C’s linking policy more strongly: preventing CRs from linking to EDs at all, preventing RECs from linking to anything below CR, etc.
If you need to override the processor’s choice for which status to link to for a particular link,
provide a status attribute containing either "ED" or "TR" on the link or a container.
6.2. Linking to Unexported Definitions
Most definition types are automatically exported and made available for cross-linking, but "dfn" type definitions aren’t, because specs often define terms for their own internal use that aren’t meant to be used outside the spec (and in particular, aren’t named in a way so as to avoid collisions).
If a spec contains a "dfn" type definition that you want to link to,
but it’s not marked for export
(either intentionally, or because it was accidentally missed and fixing the spec would be time-consuming),
using the spec attribute (defined above) will override the lack of an export declaration,
and go ahead and link to it anyway.
6.3. Configuring Linking Defaults
When there are multiple definitions for a given term
and Bikeshed can’t automatically tell which one you want,
it’ll emit a warning asking you to specify more explicitly.
You can do this per-link,
but you typically want to make the same choice every time the term is autolinked;
this can be done by adding a <pre class='link-defaults'> block,
written in the InfoTree format.
Each piece of info must have a spec, type, and text line,
and optionally a for line if necessary to further disambiguate.
Sometimes this is too fine-grained,
and you’d actually like to completely ignore a given spec when autolinking,
always preferring to link to something else.
To do this, add a <pre class='ignored-specs'> block,
written in the InfoTree format.
Each piece of info must have a spec line,
and optionally a replacedBy line,
both naming specs.
If the info has just a spec line, that spec is ignored totally by default;
linking to it requires you to manually specify a spec="" attribute on the autolink.
If the info has a replacedBy line,
then whenever an autolink has a choice between the two specs,
it’ll delete the spec value from consideration,
leaving only the replacedBy value
(plus any other specs that might be providing a definition).
6.4. Potentially-ambiguous for-less Links
If you were directed here by a Bikeshed error message,
put an explicit for value on your autolink.
(Use for="/" to link to a definition without a for value of its own).
Bikeshed’s autolinking functions as a series of filters,
some of which are optional.
For example,
if you don’t specify a for value,
then Bikeshed simply doesn’t care about the for values of definitions as it searches.
However, this doesn’t always match people’s mental models—for will specifically match a definition without a for.
Usually this is fine;
if there are multiple possible definitions,
Bikeshed will just throw up a linking error
informing you of how to be more specific.
But if you have a definition of that term with a for value in your local spec
(or your anchors block),
Bikeshed can silently select that as the correct definition to link to,
causing accidental spec corruption if you meant to link to a cross-spec definition without a for.
In other words,
if some other spec defines <dfn>term</dfn>,
and then you spec both defines <dfn for=foo>term</dfn> and links to <a>term</a> (expecting the link to go to the cross-spec definition),
you’ll be dissapointed,
but won’t know it’s wrong unless you manually check your links.
Bikeshed looks out for this situation,
and flags it as a potentially-ambiguous link,
requiring you to specify the for value explicitly.
If you want to link to the for-less cross-spec definition,
simply add for="/" to your autolink,
to indicate explicitly that you want the definition without a for value.
Otherwise, add the appropriate for value as normal.
6.5. Section Links
Sometimes you want to link to a section of a document, rather than a specific definition. Bikeshed has section links to handle this case more easily:
[[#heading-id]]
renders as:
<a href="#heading-id">§6.1 The Example Section</a>
Note that this is quite different from normal autolinks; rather than matching on text and letting Bikeshed fill in the href, you match on href and let Bikeshed fill in the text. This is because section titles change much more often than definition texts, so using text-based matching is fragile; on the other hand, their IDs tend to be stable, as they’re often linked to. Also, the section titles are often long and annoying to type, and they move around, so numbering isn’t stable.
You can also use cross-spec section links, as long as the spec is either in Bikeshed’s linking database, or the biblio database. The syntax is a mixture of a biblio reference and a section link:
[[css-flexbox-1#auto-margins]] [[CSS-access-19990804#Features]]
which renders as:
<a href="https://drafts.csswg.org/css-flexbox-1/#auto-margins">CSS Flexbox 1 §8.1 Aligning with auto margins</a> <a href="http://www.w3.org/1999/08/NOTE-CSS-access-19990804#Features">Accessibility Features of CSS §Features</a>
If Bikeshed knows about the spec, it link-checks you, and fills in the section number and heading in the generated text. If the spec is only in the bibliography database, Bikeshed just assumes that the link target exists and uses it directly in the text, because it has no way to tell what the section is named.
If the spec is multipage, like SVG,
and Bikeshed knows about it, most of the time you don’t need to do anything different -
Bikeshed will find the correct page for the heading you’re linking to.
On the rare occasions that the same heading id exists in multiple pages of the same spec, tho,
specify the page like [[svg/intro#toc]] (which indicates the #toc heading on the intro.html page).
If the desired heading is on the top-level page,
use an empty page name, like [[html/#living-standard]].
In any case, Bikeshed will throw an error,
and tell you what names it knows about so you can easily correct your link.
7. Bibliography
Bibliographical references form a special class of autolinks.
They’re typically added only via the shorthands [[FOO]] for informative references
and [[!FOO]] for normative references.
Some biblio entries come with multiple sets of urls;
at present, Bikeshed tracks a single "current" url and a single "dated" url.
In the W3C, for example, this maps to Editors Drafts and things in /TR space, respectively.
You can specify which url to use by specifying "current" or "dated" within the biblio shorthand,
like [[FOO current]],
or specify the default url to choose for all your biblio refs with the Default Ref Status.
If, for whatever reason, you need to craft a bibliography link manually,
add data-link-type=biblio, data-biblio-type=[normative | informative], and data-biblio-status=[current | dated] attributes to the link.
Unlike regular autolinks,
which link to dfn elements,
biblio autolinks cause the spec to generate entries in its "References" section,
and then link to that instead.
The bibliography database is completely separate from the autolinking database, and comes from multiple sources. The default data comes from the SpecRef project and the CSSWG’s own biblio file (preferring SpecRef’s information when the same name appears in both).
You can also add your own bibliography data, following the SpecRef JSON format:
{ "foo-bar": { "authors": [ "Tab Atkins", "Dirk Schultze" ], "href": "http://www.w3.org/TR/foo-bar/", "title": "Foo Bar Level 1", "status": "CR", "publisher": "W3C", "deliveredBy": [ "http://www.w3.org/html/wg/" ] } }
Only the "title" field is strictly necessary; the rest can be omitted if desired.
This JSON should be inline, in a <pre class=biblio> block. It can
also be in a biblio.json file in the same folder as the spec file,
but this is incompatible with the web service.
8. IDL Processing
Bikeshed can automatically process IDL blocks, marking up all relevant terms for you without any intervention, setting up definitions and autolinks as appropriate.
To activate this behavior,
simply place the IDL in the <pre class='idl'> element.
Bikeshed will consume the text content of the element
(ignoring any markup you may currently have)
and replace it with marked-up text containing dfn and a elements.
In the process of doing this, Bikeshed will also syntax-check your IDL, and report fatal errors for any mistakes. Bikeshed’s IDL parser, courtesy of Peter Linss, is intended to be forward-compatible with IDL changes, gracefully emitting unknown constructs unchanged and recovering as well as it can. If anything isn’t recognized when it should be, or the parser fails in a major, non-graceful way, please report it as an issue.
8.1. Putting Definitions Elsewhere
Quite often, you may want to have the actual definition of an IDL term (the thing that Bikeshed actually links to) somewhere in your prose near the full definition, rather than being in the IDL block.
Bikeshed will automatically produce an a in your IDL,
rather than a dfn,
if it can find a pre-existing definition of that IDL term,
including local definitions in the current spec.
However, you have to mark up the definition correctly to get this to work,
or else Bikeshed will fail to recognize there’s an external definition
and will mark up the IDL with a dfn as well.
In particular, method and attribute definitions need to have their for value set to the interface they’re a part of
(and similar with dictionary members).
Methods have some further complexity -
they should have their definition text set to contain the names of all their arguments.
For example, take the following example IDL:
interface Foo {
void bar(DOMString baz, optional long qux);
};
To have Bikeshed recognize a definition for the bar() method placed elsewhere,
it must look something like <dfn method for=Foo title="bar(baz, qux)">bar(DOMString baz, optional long qux)</dfn>.
Additionally, it should define alternate linking texts for omittable arguments,
like <dfn method for=Foo title="bar(baz, qux)|bar(baz)">bar(DOMString baz, optional long qux)</dfn>.
This way any valid call signature can be used to autolink.
Note that arguments are omittable if they’re marked with optional, or are variadic (like long... qux), or have a default value.
Nullable arguments (like long? qux) are not omittable.
(If you are fine with the dfn being in the IDL block,
Bikeshed will do all of this for you.)
Unless all arguments can be omitted, the definition text should not have an alternative with empty args.
For convenience, however, Bikeshed will allow autolinks with empty argument lists to work,
as long as it can resolve the link unambiguously.
For example, {{Foo/bar()}} will autolink to the method defined above,
despite it not being a valid call signature,
as long as there isn’t an overload of bar() that it might also apply to.
(The above applies to all functionish types: method, constructor, stringifier, etc.)
Marking up argument definitions is similar.
To mark up the baz argument of the above method, for example,
do <dfn argument for="Foo/bar(baz, qux)">baz</dfn>.
You should use the full call signature of the method.
8.2. Linking to Stringifiers
Linking to a stringifier is a little complicated, because WebIDL allows four different syntaxes for it.
The stringifier keyword itself is always linkable;
it’s a "dfn" type definition with for=MyInterface and linking text "stringification behavior".
Like any other IDL construct,
you can instead define the term yourself in the same way,
and the IDL will link to your definition instead,
like <dfn dfn for=MyInterface>stringification behavior</dfn>.
This is generally what you should use to link to the stringifier,
as it’ll maintain the links even if you change which syntax form you use.
If you use the "stringifier attribute" form,
like stringifier attribute DOMString href;,
you can also just link/dfn the attribute as normal.
If you use the "stringifier method" form,
like stringifier DOMString foo(long bar);,
you can also just link/dfn the method as normal,
like <dfn stringifier for=MyInterface>foo(bar)</dfn>.
(Note that it’s a "stringifier" type definition,
not "method".)
If you use the "anonymous stringifer method" form,
like stringifier DOMString(long bar),
you can still technically link/dfn it as a stringifier method.
It doesn’t have a name, so we invent one -
it’s called __stringifier__(), a la Python’s magic methods.
(Note the two underscores on each side.)
You should almost never need to do this;
the only reason to need to specify the method name
(rather than just linking to the keyword, as described above)
is if you’re linking/dfning an argument to the method,
and need to specify a for value for it.
8.3. Turning Off Processing
If for whatever reason you don’t want your IDL block to be processed by Bikeshed,
simply use another element, or another class.
If you really want to use <pre class=idl>,
you can add a data-no-idl attribute to the element.
Bikeshed will leave these elements alone.
9. Boilerplate Generation
The processor automatically generates nearly all of a spec’s boilerplate, the text that is repeated nearly identically across all specs.
Generally, you won’t need to understand what’s going on here in order to use the processor - it’ll just automatically do the right thing.
For help in creating new boilerplate files for your organization, see §9.6 Creating New Boilerplate Files For Your Organization.
9.1. Groups
Much of the boilerplate is determined based on the Group metadata. If unspecified, it defaults to a generic set of boilerplate that is generally appropriate for most things, without making reference to any particular standards body or the like. However, to obtain correct boilerplate for a given standards body, "Group" can be used.
Several groups are already accommodated with appropriate inclusion files:
-
"csswg", as mentioned.
-
"dap", for the Device and Sensors Working Group
-
"fxtf", for the FX Task Force
-
"houdini", for the Houdini Task Force
-
"svg", for the SVG Working Group
-
"webappsec", for the WebApps Security Working Group
-
"whatwg", for the WHATWG
-
"wg21", for the C++ Standards Committee
-
"tc39", for ECMAScript TC-39
You can put whatever value you want into the "Group" value, though. Unrecognized values will just use the default boilerplate files. If you want to add specialized boilerplate files for your group, check out the File-Based Includes section, later in this document, and write your own files.
9.2. Text Macros
Several text "macros" are defined by the spec’s metadata,
and can be used anywhere in the spec to substitute in the spec they stand for by using the syntax [FOO].
Note that this is similar to the syntax for bibliography references, but it has only a single set of [] characters, and the text must be uppercase.
The following macros are defined:
-
[TITLE]gives the spec’s full title, as extracted from either the H1 or the spec metadata. -
[H1]gives the desired document heading, in case the in-page title is supposed to be different from the<title>element value. -
[SHORTNAME]gives the document’s shortname, like "css-cascade". -
[VSHORTNAME]gives the "versioned" shortname, like "css-cascade-3". -
[STATUS]gives the spec’s status. -
[LONGSTATUS]gives a long form of the spec’s status, so "ED" becomes "Editor’s Draft", for example. -
[STATUSTEXT]gives an additional status text snippet. -
[LATEST]gives the link to the undated /TR link, if it exists. -
[VERSION]gives the link to the ED, if the spec is an ED, and otherwise constructs a dated /TR link from today’s date. -
[ABSTRACT]gives the document’s abstract. -
[ABSTRACTATTR]gives the document’s abstract, correctly escaped to be an attribute value. -
[YEAR]gives the current year. -
[DATE]gives a human-readable date. -
[CDATE]gives a compact date in the format "YYYYMMDD". -
[ISODATE]gives a compact date in iso format "YYYY-MM-DD". -
[DEADLINE]gives a human-readable version of the deadline data, if one was specified. -
[LOGO]gives the url of the spec’s logo -
[REPOSITORY]gives the name of the VCS repository the spec is located in; this is currently only filled when the spec source is in a GitHub repository. (Patches welcome for more repo-extraction code!)
As these are substituted at the text level, not the higher HTML level, you can use them anywhere, including in attribute values.
You can mark a macro as "optional" by appending a ? to its name,
like [DATE?].
This will cause Bikeshed to just remove it
(replace it with the empty string)
if it can’t find a definition,
rather than throwing an error.
Like most other markup shorthands,
text macros can be "escaped" by prepending a backslash,
like \[TITLE].
When Bikeshed sees this,
it will remove the slash and leave the text alone.
This is sometimes necessary when code examples in your doc (such as a regex)
accidentally look like text macros.
9.3. Boilerplate Sections
The location of the boilerplate sections are indicated by elements with data-fill-with='' attributes.
If the elements contain anything, they’re emptied before being filled with the appropriate boilerplate.
The valid data-fill-with='' values are:
-
"table-of-contents" for the ToC
-
"spec-metadata" for the
dlof spec data that’s in the header of all of our specs -
"abstract" for the spec’s abstract
-
"status" for the status section
-
"logo" for the W3C logo
-
"copyright" for the W3C copyright statement
-
"warning" for the relevant spec warning, if one was indicated in the metadata.
-
"references" for the bibliography refs
-
"index" for the index of terms (all the
dfnelements in the spec) -
"property-index" for the table summarizing all properties defined in the spec
-
"issues-index"
Additionally, "header" and "footer" boilerplate files are used to put content at the start and end of your document. Most or all of the above boilerplate sections should actually show up here, in the header and footer, rather than being manually specified in your source file.
9.3.1. Default Boilerplate
Some sections listed above are generated by default;
if you don’t put an explicitly data-fill-with container in your document,
they’ll generate anyway (if they have anything to fill themselves with),
appending themselves to the end of the body.
These sections are:
-
all of the indexes: "index", "property-index", and "issues-index"
-
"references"
Again, these will only auto-generate if there is something for them to do; if your spec doesn’t define any CSS properties, for example, the "property-index" boilerplate won’t generate. If you want to suppress their generation even when they do have something to do, use the Boilerplate metadata, like:
<pre class="metadata"> Boilerplate: property-index no </pre>
9.3.2. Overriding Boilerplate
Sometimes a file-based boilerplate (see below) that is appropriate for most of the specs in your group
isn’t quite right for your specific spec.
Any boilerplate, file-based or Bikeshed-generated,
can be overriden by custom text of your choosing.
Just add an element to your source document with the content you’d like to show up in place of the offending boilerplate,
and add a boilerplate="foo" attribute to the container,
specifying which boilerplate section is being replaced.
Bikeshed will automatically remove that element from you document, and instead inject its contents in place of the boilerplate that it would normally provide.
9.4. Table of Contents
The headings in the spec are automatically numbered, and a table of contents automatically generated.
Any heading h2 to h6 (that is, skipping only the document-titling h1)
is automatically numbered by having a <span class='secno'>...</span> prepended to its contents.
You can avoid this behavior for a heading and all of its subsequent subheadings
by adding class="no-num" to the heading.
Similarly, a ToC is generated to match.
Headings and their subheadings can be omitted from the ToC
by adding class="no-toc" to them.
The processor assumes that your headings are numbered correctly.
It does not yet pay attention to the HTML outline algorithm,
so using a bunch of h1s nested in sections will have very wrong effects.
Headings also automatically gain a self-link pointing to themselves, to enable people to easily link to sections without having to return to the ToC.
9.5. File-based Includes
Several of the data-fill-with values (those that are static, rather than generated from in-document data) actually come from sets of .include files in the include/ directory.
The base files are simply named "foo.include", where "foo" is the name of the data-fill-with value. They can be specialized, however, to particular working groups, and to particular document statuses.
Putting the boilerplate in a folder named after the group,
like csswg/header.include,
specializes it for that group (specified in the spec’s metadata).
Adding a "-STATUS" to the filename specializes it for the status (same).
These can be used together, like "csswg/status-CR.include".
The processor will first look for the "group/foo-STATUS.include" file, failing over to "group/foo.include", then "foo-STATUS.include", and finally "foo.include".
9.6. Creating New Boilerplate Files For Your Organization
Bikeshed’s default boilerplate generates a functional and reasonably attractive spec, but if your group has specific style requirements, you can produce your own boilerplate files. This section is a basic guide to developing these files.
The most important part of the boilerplate is the header.include and footer.include file.
These define the parts of the spec HTML that precede and follow your actual spec content,
so the source file can contain only the actual spec text,
and all specs in the same organization can look similar.
Here is a basic example header.include file:
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Bikeshed Documentation</title> <style> ... </style> </head> <body class="h-entry"> <div class="head"> <p data-fill-with="logo"></p> <h1 id="title" class="p-name no-ref">Bikeshed Documentation</h1> <h2 id="subtitle" class="no-num no-toc no-ref">Living Standard, <span class="dt-updated"><span class="value-title" title="20170228">28 February 2017</span></h2> <div data-fill-with="spec-metadata"></div> <div data-fill-with="warning"></div> <p class='copyright' data-fill-with='copyright'></p> <hr title="Separator for header"> </div> <h2 class='no-num no-toc no-ref' id='abstract'>Abstract</h2> <div class="p-summary" data-fill-with="abstract"></div> <div data-fill-with="at-risk"></div> <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2> <div data-fill-with="table-of-contents"></div>
This uses several of Bikeshed’s boilerplating features:
-
Text replacement, via the
\[FOO]macros. These macros are prepopulated by Bikeshed, either from metadata in the spec (like[TITLE]) or from environment data (like[DATE]). The full list of text macros can be found at §9.2 Text Macros -
Boilerplate pieces, via empty container elements with
data-fill-withattributes. The list of Bikeshed-provideddata-fill-withvalues can be found at §9.3 Boilerplate Sections). At minimum, you want to include theabstract,table-of-contents, andspec-metadatasections here; they’re all most useful at the top of the document.
10. Railroad Diagrams
A railroad diagram is a particular way of visually representing a structure roughly equivalent to regular expressions, or simple grammars. They tend to be more readable and easier to grok than their equivalents written in terse regexps, and smaller than their equivalents written in explicit parsers.
Here’s an example of a railroad diagram, this one describing the syntax of valid IDENT tokens in CSS:
Bikeshed supports the automatic generation of railroad diagrams from a simplified DSL. To use, simply embed a diagram description in a <pre class='railroad'> element - it’ll get replaced by an appropriate svg element.
10.1. The Diagram Language
Diagrams are described by a custom DSL that somewhat resembles Python.
A railroad diagram consists of a number of nested elements, each of which may contain multiple children. Each element is specified as a command followed by a colon, possibly followed by additional data (the prelude), and the element’s children indented on following lines, like:
T: /* ZeroOrMore: N: anything but * followed by / T: */
This draws the following diagram:
The top-level elements are assumed to be a sequence of elements in the diagram. Inside of a diagram, any of the elements may be used. Elements are split into two groups: containers and text.
The containers hold other elements, and modify their semantics:
-
Sequence (And, Seq) - used for sequences of elements which must all be selected in order. Like concatenation in regexes. Takes 1 or more children.
-
Stack - A sequence that arranges its children vertically. Useful for preventing diagrams from becomming excessively wide. Takes 1 or more children.
-
Choice (Or) - used for a choice between elements. Like the
|character in regexes. Takes 1 or more children. Optionally, the "default" index may be provided in the prelude (defaulting to 0). -
Optional (Opt)- used for an element that’s optional. Like the
?character in regexes. Takes 1 child. Optionally, the wordskipmay be provided in the prelude to indicate that this term is skipped by default. -
OneOrMore (Plus)- used for an element that can be chosen one or more times. Like the
+character in regexes. Takes 1 or 2 children: the first child is the element being repeated, and the optional second child is an element repeated between repetitions. -
ZeroOrMore (Star) - same as OneOrMore, but allows the element to be chosen zero times as well (skipped entirely). Like the
*character in regexes. Like Optional, the keywordskipmay be provided in the prelude to indicate that the "default option" is to skip it (repeat 0 times). -
Terminal (T) - represents a "terminal" in the grammar, something that can’t be expanded any more. Generally represents literal text.
-
NonTerminal (N) - represents a "non-terminal" in the grammar, something that can be expanded further.
-
Comment (C) - represents a comment in the railroad diagram, to aid in reading or provide additional information. This is often used as the repetition value of a OneOrMore or ZeroOrMore to provide information about the repetitions, like how many are allowed.
-
Skip (S) - represents nothing, an empty option. This is rarely necessary to use explicitly, as containers like Optional use it automatically, but it’s occasionally useful when writing out a Choice element where one option is to do nothing.
The text elements only contain text, not other elements. Their values are given in their preludes.
11. Source-File Processing: bikeshed source
Sometimes it’s the source file you want to preprocess, if there is some feature you want literally in your source that is hard or annoying to type in yourself. Bikeshed has some options for doing this as well.
All of these commands are accessed from the source sub-command,
like bikeshed source.
You can run individual commands by specifying their relevant flag
(see bikeshed source -h for a list),
or run all of them by not passing any flags.
11.1. Big Text
When editing a large spec, it’s easy to get lost in its length, and have to spend some time scrolling back and forth to find particular sections.
The Sublime Text editor has a special feature, the minimap, which shows an extremely-zoomed out version of your document while you scroll, so you can recognize where you are in the file by the shape of your code. This can be made even easier by putting extra-large "ASCII art" text in your source to label major sections, so they show up visibly in the minimap as section markers.
Bikeshed can auto-generate this "ASCII art" text for you
with its --big-text command.
Just add an HTML comment to your document on its own line that looks like:
<!-- Big Text: Your Text -->
If you run bikeshed source --big-text,
Bikeshed will replace it with a comment that looks like:
<!-- ██ ██ ███████ ██ ██ ████████ ████████ ████████ ██ ██ ████████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████████ ██ ██████ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ███████ ███████ ██ ██ ██ ████████ ██ ██ ██ -->
Which is clearly visible from Sublime’s minimap!
Appendix A: Bikeshed’s "InfoTree" Format
Bikeshed’s custom text formats attempt to be fairly regular; most of them involve specifying key/value pairs, and are line-based. For example, Bikeshed’s metadata format is one key/value pair per line, with a colon between the key and the value.
The InfoTree format, used by several things in Bikeshed, is similar. It’s used when you need to specify data consistenting of multiple key/value pairs, where it’s common that multiple entries share some of that data. The InfoTree format makes this easy to read, write, and maintain.
Specifying Information on a Single Line
The simplest way to provide a piece of information is by putting all the key/value pairs on a single line. In the InfoTree format, this is done by putting a colon between the key and value, and separating the pairs with semicolons. For example, here is an example of two "anchor" entries:
urlPrefix: https://encoding.spec.whatwg.org/; type: dfn; text: ascii whitespace urlPrefix: https://encoding.spec.whatwg.org/; type: dfn; text: utf-8
This specifies two entries, each with three keys: urlPrefix, type, and text.
Nesting Information to Share Pieces
When multiple pieces of information share some key/value pairs, you can use nesting to indicate this, so you don’t have to repeat yourself. Here’s the same two entries as before, but using nesting to share their common information:
urlPrefix: https://encoding.spec.whatwg.org/; type: dfn text: ascii whitespace text: utf-8
Just like the previous, this defines two entries, each with three key/value pairs
Now it’s clearer, though, that the two entries share their urlPrefix and type data,
and you only have to maintain the common data in one place.
Additional Details
The order that keys are specified in is irrelevant. Feel free to rearrange them for readability or more effective nesting.
You can specify the same key multiple times; the values will be collected into an array for later processing. (Each user of InfoTree will define whether multiple values for a key is valid or not, and what it means.) The order that the values appear in is preserved, as it might be important. (For example, in the anchor format, multiple urlPrefix values are concatenated together, to help specify urls in multipage specs.)
Additional semicolons are silently ignored; in other words, empty entries get dropped, so you can put a final semicolon at the end of the line or not, as you prefer.
