§ Spec-Up Example
Specification Status: Draft
Latest Draft: https://identity.foundation/spec-up
- Editors:
- Daniel Buchner
- Participate:
- GitHub repo
- File a bug
- Commit history
§ Abstract
Let’s face it, other tools and generators for writing technical specifications aimed at standards bodies or industry groups are cumbersome, underwhelming, and lack the features you might want in a technical specification document. Spec-Up’s goal is to deliver you a better spec-writing experience with far less effort and tedium than other tools in the ecosystem. Spec-Up is a simple tool that auto-generates great specs from markdown. The version of markdown Spec-up uses contains all the same features you might expect from common implementations, like GitHub, but adds much more, including notice blocks, complex tables, charts, advanced syntax highlighting, UML diagrams, etc.
§ Getting Started
Using Spec-Up is easy peasy lemon squeezy:
-
npm install spec-up
-
Create a
specs.json
file in the root folder of your repository to specify configuration values used in the generation of your spec documents. The values in yourspecs.json
file include things like where your spec’s markdown files are located, where to output the generated spec document, and various metadata values used in rendering, such as the title, logo, and repo links for each of your specs. The following are the required/optional fields supported in thespecs.json
config file:spec_directory
(STRING, required) - You must specify the repo-root-relative location of your spec’s markdown file directory. You MUST name your spec’s markdown filespec.md
and locate it in yourspec_directory
for the tool to automatically find and use it for rendering. If you want to use a different name for the markdown file, or you have multiple markdown files you would like the tool to assemble into one document, you must specify them using the optionalmarkdown_paths
field described below. See the “multi-file” example in the spec-up repo.title
(STRING, required) - You must add a title for your spec, which will be rendered in the generated document’s H1 text and page title.markdown_paths
(ARRAY, optional) - If you want to name your spec’s markdown file something other thanspec.md
, or you have multiple files you would like assembled into a single output document, you must specify their paths as array entries in the order you would like them assembled. The paths in this array are assumed to be based on thespec_directory
you specified, so DO NOT repeat the full root relative path.katex
(BOOLEAN, optional) - To enable TeX support via KaTeX, set this property totrue
. After rendering, be sure to copy thefonts/
subdirectory, containing the necessary web fonts.output_path
(STRING, optional) - If you want the generated spec document to be output to a different location than thespec_directory
you specified (e.g. the project root for GitHub Pages publishing) you can specify another root relative path (use./
for root), and the tool will write the document file there instead.
-
In your main node.js file, drop in this bad boy:
require('spec-up')()
Boom! That’s it. Spec-Up will auto-detect modifications to files in your spec_directory
and auto-generate your spec’s updated HTML document every time you save a change.
Usage
If your spec.json
and package.json
and package-lock.json
files are in working order and in the root folder of the repo from which it will be deployed, Spec-up can be called by command line (from the root of your repo) in three different modes:
command | behavior |
---|---|
npm run edit |
after rendering, this will stay running and the gulp library will watch the source files in your spec directory/ies for changes and re-render any time you save a file. Opening these rendered files in a browser and refreshing them will keep you up to date. |
npm run render |
this renders the site once and does not keep a gulpy watch on the underlying files. |
npm run dev |
this enables debugging features. |
§ Table of Contents
<-- You see that beautiful TOC over there to your left? (tap the header link to slide it out on mobile) Yeah, you don’t need to do a damn thing, that just magically appears based on your use of h2
, h3
, and h4
headings.
§ Term References
§ Definition Lists
Many specs may want to include a section for terminology references, and Definition Lists are a great way to do that. Here’s how to leverage Spec-Up’s automatic term reference features via Definition List markup:
[[def: Term 1, Term One]]: ~ This is the first term we will define. [[def: Term 2, Term Two]]: ~ This is the second term, but not the last. [[def: Term 3, Term Three]]: ~ This is the last term, because you know what they say: third term's the charm!
- Term 1:
- This is the first term we will define.
- Term 2:
- This is the second term, but not the last.
- Term 3:
- This is the last term, because you know what they say: third term’s the charm!
Now let’s refer to some of the terms defined above to show how the auto-linking of terms works: Term 1, Term Two, Term 3. Additionally, as long as you define your terms using Definition Lists (as seen in the markdown above), you will be able to hover any reference to a term to see a tooltip with its definition.
§ Table-defined Terms
You can also reference table-oriented terms and definitions which are decomposed into heading-titled attributes in distinct cells:
Variable | Default Value | Max Value ------------------- | -------------- | --------- [[def: Variable 1]] | 123 | 9999
Variable | Default Value | Max Value |
---|---|---|
Variable 1 | 123 | 9999 |
Anytime you add a definition of a term in the first column of a table, like Variable 1, it will link to the cell and display a tooltip with the entire set of row values when you hover the term.
§ External Term References
It is possible to include references to terms from external spec-up generated specifications. To include a source you would like to pull references from include an external_specs
array in your spec config. The value should be a key/value object where the key is used in the external reference below and the value is the URL of the external spec.
{
"specs": [
{
...
"external_specs": [
{"PE": "https://identity.foundation/presentation-exchange"}
]
}
]
}
To include an external term reference within your spec use the following format [[xref: {title}, {term}]]
where {title}
is the title given to the spec in the config and {term}
is the term being used. For example using the PE spec given in the example above Holder
§ Blockquote
To be, or not to be, that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles And by opposing end them. To die—to sleep, No more;
§ Notices
::: note Basic Note Check this out. :::
Check this out.
Here’s another.
And one more!
One last note!!!
::: issue Issue Notice I take issue with that, kind sir. :::
I take issue with that, kind sir.
::: warning Warning Notice Houston, I think we have a problem :::
Houston, I think we have a problem
::: todo Really Important Get this done! :::
Get this done!
::: example Code Example Put your code block here :::
// Some comment in JSON
{
"foo": "bar",
"baz": 2
}
§ Content Insertion
Use the following format to pull in content from other files in your project:
This text has been inserted here from another file: [[insert: ./single-file-test/assets/test.text]]
This text has been inserted here from another file: Beam me in, Scotty!
You can even insert content within more complex blocks, like the JSON object below which is being pulled in and rendered in a syntax-highlighted example block:
::: example Code Example ```json [[insert: ./single-file-test/assets/test.json]] ``` :::
{
"foo": {
"bar": 1
}
}
§ Tables
Stage | Direct Products | ATP Yields ----: | --------------: | ---------: Glycolysis | 2 ATP || ^^ | 2 NADH | 3--5 ATP | Pyruvaye oxidation | 2 NADH | 5 ATP | Citric acid cycle | 2 ATP || ^^ | 6 NADH | 15 ATP | ^^ | 2 FADH2 | 3 ATP | **30--32** ATP ||| [Net ATP yields per hexose]
Stage | Direct Products | ATP Yields |
---|---|---|
Glycolysis | 2 ATP | |
2 NADH | 3–5 ATP | |
Pyruvaye oxidation | 2 NADH | 5 ATP |
Citric acid cycle | 2 ATP | |
6 NADH | 15 ATP | |
2 FADH2 | 3 ATP | |
30–32 ATP |
|--|--|--|--|--|--|--|--| |♜| |♝|♛|♚|♝|♞|♜| | |♟|♟|♟| |♟|♟|♟| |♟| |♞| | | | | | | |♗| | |♟| | | | | | | | |♙| | | | | | | | | |♘| | | |♙|♙|♙|♙| |♙|♙|♙| |♖|♘|♗|♕|♔| | |♖|
♜ | ♝ | ♛ | ♚ | ♝ | ♞ | ♜ | |
♟ | ♟ | ♟ | ♟ | ♟ | ♟ | ||
♟ | ♞ | ||||||
♗ | ♟ | ||||||
♙ | |||||||
♘ | |||||||
♙ | ♙ | ♙ | ♙ | ♙ | ♙ | ♙ | |
♖ | ♘ | ♗ | ♕ | ♔ | ♖ |
§ Sequence Diagrams
```mermaid sequenceDiagram Alice ->> Bob: Hello Bob, how are you? Bob-->>John: How about you John? Bob--x Alice: I am good thanks! Bob-x John: I am good thanks! Note right of John: Bob thinks a long
long time, so long
that the text does
not fit on a row. Bob-->Alice: Checking with John... Alice->John: Yes... John, how are you? ```
long time, so long
that the text does
not fit on a row. Bob-->Alice: Checking with John... Alice->John: Yes... John, how are you?
§ Flows
```mermaid graph TD A[Start] --> B{Is it?} B -->|Yes| C[OK] C --> D[Rethink] D --> B B -->|No| E[End] ```
§ Charts
```chart { "type": "pie", "data": { "labels": [ "Red", "Blue", "Yellow" ], "datasets": [ { "data": [ 300, 50, 100 ], "backgroundColor": [ "#FF6384", "#36A2EB", "#FFCE56" ], "hoverBackgroundColor": [ "#FF6384", "#36A2EB", "#FFCE56" ] } ] } } ```
§ Syntax Highlighting
```json { "@context": "https://www.w3.org/ns/did/v1", "id": "did:example:123456789abcdefghi", "authentication": [{ "id": "did:example:123456789abcdefghi#keys-1", "type": "RsaVerificationKey2018", "controller": "did:example:123456789abcdefghi", "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n" }], "service": [{ "id":"did:example:123456789abcdefghi#vcs", "type": "VerifiableCredentialService", "serviceEndpoint": "https://example.com/vc/" }] } ```
{
"@context": "https://www.w3.org/ns/did/v1",
"id": "did:example:123456789abcdefghi",
"authentication": [{
"id": "did:example:123456789abcdefghi#keys-1",
"type": "RsaVerificationKey2018",
"controller": "did:example:123456789abcdefghi",
"publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n"
}],
"service": [{
"id":"did:example:123456789abcdefghi#vcs",
"type": "VerifiableCredentialService",
"serviceEndpoint": "https://example.com/vc/"
}]
}
§ TeX Math Equations
When the katex
option is enabled, the KaTeX math engine is used for TeX rendering. You can find a list of supported features and examples here: https://katex.org/docs/supported.html.
§ Tab Panels
{
"foo": "foo",
"baz": 1
}
{
"foo": "bar",
"baz": 2
}
§ Fancy Links
Spec-Up automatically upgrades the links of certain sites, like GitHub. GitHub is the only supported site with Fancy Links right now, but we’ll be adding more as we go.
§ GitHub
- Issues
- Source:
https://github.com/decentralized-identity/presentation-exchange/issues/119
- Render: https://github.com/decentralized-identity/presentation-exchange/issues/119
- Source:
- Pull Requests
- Source:
https://github.com/decentralized-identity/sidetree/pull/863
- Render: https://github.com/decentralized-identity/sidetree/pull/863
- Source:
- Releases
- Source:
https://github.com/decentralized-identity/sidetree/releases/tag/v0.9.1
- Render: https://github.com/decentralized-identity/sidetree/releases/tag/v0.9.1
- Source:
- Projects
- Source:
https://github.com/decentralized-identity/sidetree/projects/1
- Render: https://github.com/decentralized-identity/sidetree/projects/1
- Source:
§ External Spec References
You can reference external specifications from IETF, W3C, and WHATWG as follows:
- Anywhere in your document you want to referece an external specification, use the
spec
-prefixed custom token format:[[spec:RFC4122]]
- Wherever in your document you want to print out all your external specification references, use the
spec
custom token format without any spec name:[[spec]]
- If you want to split up your references into groups (e.g. normative vs informative), just make sure to use dash-delimited unique reference grouping string in your custom tokens:
[[spec-norm:RFC4122]]
,[[spec-inform:RFC4122]]
,[[spec-foo:RFC4122]]
, etc. - To print out a custom group’s references, just include the grouping string for a given set of references in a custom token without any spec name:
[[spec-norm]]
,[[spec-inform]]
,[[spec-foo]]
.
Here are a set of example references that are distributed among the reference groups spec
, spec-norm
, spec-inform
:
- [RFC3548] (
[[spec:RFC3548]]
) - [RFC7518] (
[[spec:RFC7518]]
) - [DID-CORE] (
[[spec-norm:DID-CORE]]
) - [DID-SPEC-REGISTRIES] (
[[spec-norm:DID-SPEC-REGISTRIES]]
) - [RFC6901] (
[[spec-inform:RFC6901]]
) - [RFC7230] (
[[spec-inform:RFC7230]]
)
§ Default References
This is what is printed out when you include the [[spec]]
custom token in your Markdown:
- RFC3548
- The Base16, Base32, and Base64 Data Encodings. S. Josefsson, Ed.; 2003-07. Status: Informational.
- RFC7518
- JSON Web Algorithms (JWA). M. Jones; 2015-05. Status: Proposed Standard.
§ Normative References
This is what is printed out when you include the [[spec-norm]]
custom token in your Markdown:
- DID-CORE
- Decentralized Identifiers (DIDs) v1.0. Manu Sporny; Amy Guy; Markus Sabadello; Drummond Reed; 2022-07-19. Status: REC.
- DID-SPEC-REGISTRIES
- DID Specification Registries. Orie Steele; Manu Sporny; 2023-09-11. Status: NOTE.
§ Informative References
This is what is printed out when you include the [[spec-inform]]
custom token in your Markdown:
- RFC6901
- JavaScript Object Notation (JSON) Pointer. P. Bryan, Ed.; K. Zyp; M. Nottingham, Ed.; 2013-04. Status: Proposed Standard.
- RFC7230
- Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. R. Fielding, Ed.; J. Reschke, Ed.; 2014-06. Status: Proposed Standard.