spec-md
Version:
Renders Markdown with some additions into an HTML format commonly used for writing technical specification documents. Markdown additions include code syntax highlighting, edit annotations, and the definition of algorithms and grammar productions.
1,172 lines (972 loc) • 21.6 kB
CSS
@media (prefers-color-scheme: light) {
:root {
--color-foreground: #333333;
--color-background: #ffffff;
--color-light-grey: #ccc;
--color-grey: #666666;
--color-white: #fff;
--color-link: #3b5998;
--color-subsection-link: var(--color-foreground);
--color-toc-link: var(--color-foreground);
--color-toc-id: var(--color-link);
--color-toggle-border: #bbc;
--color-sidebar-background: #f0f0f0;
--color-sidebar-viewing-link: #8b9;
--color-sidebar-toggle-button: rgba(0, 0, 0, 0.7);
--color-sidebar-shadow-inset: rgba(0, 0, 0, 0.05);
--color-sidebar-shadow: rgba(0, 0, 0, 0.04);
--color-sidebar-large-shadow: rgba(0, 0, 0, 0.08);
--color-pre-background: #fafafa;
--color-pre-border: #e9e9e9;
--color-code-background: rgba(0, 0, 0, 0.03);
--color-spec-todo: var(--color-grey);
--color-spec-example: #fafaff;
--color-spec-example-border: #bbbbff;
--color-spec-counter-example: #fffafa;
--color-spec-counter-border: #ffbbbb;
--color-spec-counter-example-link: #98593b;
--color-spec-added-border: #396;
--color-spec-removed-border: #933;
--color-spec-prose: var(--color-grey);
--color-spec-quantifier-list: var(--color-link);
--color-spec-quantifier-optional: #83238e;
--color-spec-condition: #1c7758;
--color-spec-param: var(--color-grey);
--color-spec-rx: var(--color-foreground);
--color-spec-note-border: #f4e925;
--color-spec-note-background: #fefef3;
--color-spec-note-first-link: #6c6613;
--color-source-link: var(--color-light-grey);
--color-table-header: #f9f9f9;
--color-table-header-border: #d0d0d0;
--color-token-inserted: hsla(241, 71%, 34%, 0.69);
--color-token-deleted: hsla(324, 92%, 33%, 0.74);
--color-inserts-background: rgba(0, 200, 30, 0.08);
--color-deletions-background: rgba(200, 0, 0, 0.08);
--selection-background-color: #cacee0;
--selection-background-color-link: #f0babe;
}
.selection-link:hover {
--selection-background-color: #3b5998;
}
}
@media (prefers-color-scheme: dark) {
:root {
--color-foreground: #b6b6b6;
--color-background: #262626;
--color-light-grey: #373737;
--color-grey: #828282;
--color-white: rgb(29, 29, 29);
--color-link: #89b7da;
--color-subsection-link: var(--color-foreground);
--color-toc-link: var(--color-foreground);
--color-toc-id: var(--color-link);
--color-toggle-border: #bbc;
--color-sidebar-background: #323232;
--color-sidebar-viewing-link: #8b9;
--color-sidebar-toggle-button: rgba(220, 220, 220, 0.7);
--color-sidebar-shadow-inset: rgba(0, 0, 0, 0.05);
--color-sidebar-shadow: rgba(0, 0, 0, 0.04);
--color-sidebar-large-shadow: rgba(0, 0, 0, 0.08);
--color-pre-background: #2e2e2e;
--color-pre-border: #3a3a3a;
--color-code-background: rgba(41, 41, 41, 0.03);
--color-spec-todo: var(--color-grey);
--color-spec-example: #2b2b35;
--color-spec-example-border: #4d4d6d;
--color-spec-counter-example: #322828;
--color-spec-counter-border: #664040;
--color-spec-counter-example-link: #ff702d;
--color-spec-added-border: #396;
--color-spec-removed-border: #933;
--color-spec-prose: var(--color-grey);
--color-spec-quantifier-list: var(--color-link);
--color-spec-quantifier-optional: #c689ce;
--color-spec-condition: #6fa889;
--color-spec-param: var(--color-grey);
--color-spec-rx: var(--color-foreground);
--color-spec-note-border: #605e39;
--color-spec-note-background: #303028;
--color-spec-note-first-link: #f0e330;
--color-source-link: var(--color-grey);
--color-table-header: #373737;
--color-table-header-border: #525252;
--color-token-inserted: hsla(241, 63%, 70%, 0.69);
--color-token-deleted: hsla(325, 64%, 67%, 0.74);
--color-inserts-background: rgba(0, 200, 30, 0.08);
--color-deletions-background: rgba(200, 0, 0, 0.08);
--selection-background-color: #656565;
--selection-background-color-link: #f0babe;
}
.selection-link:hover {
--selection-background-color: #829edb;
}
}
:root {
color: var(--color-foreground);
background-color: var(--color-background);
font-family: var(--font-family);
font-size: 15px;
line-height: 1.5;
--mono-font-size: 13px;
--indent: 1rem;
--list-indent: 1.5rem;
--dfn-indent: 0rem;
--font-family: Cambria, "Palatino Linotype", Palatino, "Liberation Serif",
serif;
--font-family-monospace: Consolas, Monaco, "Andale Mono", "Ubuntu Mono",
monospace;
}
@media (min-width: 720px) {
:root {
font-size: 17px;
--mono-font-size: 15px;
--indent: 2rem;
--list-indent: 2rem;
--dfn-indent: 2rem;
}
}
body {
margin: 3rem 0 3rem;
}
article {
margin: 0 1rem;
}
@media (min-width: 720px) {
body {
margin: 6rem auto 3rem;
max-width: 800px;
padding-left: 75px;
padding-right: clamp(0px, calc((100vw - 800px) * 0.25), 75px);
}
}
/* Source Links */
.source-link {
display: none;
}
@media screen and (min-width: 720px) {
.source-link {
display: block;
position: absolute;
width: 18px;
fill: var(--color-source-link);
opacity: 0.3;
}
.source-link:hover {
opacity: 1;
}
}
/* Selections */
.outdated-selection-link,
.selection-link {
position: absolute;
display: block;
color: var(--color-white);
background: var(--selection-background-color);
border-radius: 4px;
font-size: 36px;
height: 23px;
line-height: 48px;
text-align: center;
text-decoration: none;
width: 25px;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.outdated-selection-link:hover,
.selection-link:hover {
text-decoration: none;
}
.outdated-selection-link:before,
.selection-link:before {
border: 5px solid transparent;
content: "";
height: 0;
margin-top: -5px;
margin-right: -5px;
position: absolute;
right: 1px;
top: 50%;
width: 0;
}
@media (max-width: 719px) {
.outdated-selection-link:before,
.selection-link:before {
border-bottom-color: var(--selection-background-color);
border-top: 0;
right: 50%;
top: 1px;
}
}
@media (min-width: 720px) {
.outdated-selection-link:before,
.selection-link:before {
border-left-color: var(--selection-background-color);
border-right: 0;
right: 1px;
top: 50%;
}
}
.outdated-selection-link {
background: var(--selection-background-color-link);
font-size: 21px;
font-weight: 800;
line-height: 27px;
}
.outdated-selection-link:hover:after {
content: "This selection content has changed since this link was created.";
font: 9pt/11pt var(--font-family);
position: absolute;
display: block;
white-space: nowrap;
padding: 2px 5px 1px;
top: -20px;
background: black;
color: var(--color-white);
}
/* Links */
a {
color: var(--color-link);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Images */
img {
max-width: 100%;
}
/* Definitions */
dl {
margin: 1rem 0 1rem var(--dfn-indent);
}
dd {
margin: 0.25em 0 0.5em var(--indent);
}
dd + dd {
margin-top: 1rem;
}
dfn,
.spec-ref {
font-style: italic;
}
dfn > a,
.spec-ref > a {
color: inherit;
}
/* Section headers */
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: bold;
margin: 3em 0 1em;
position: relative;
}
@media (min-width: 720px) {
header > h1 {
margin: 6em 0 3em;
}
}
h1 {
font-size: 1.5em;
margin-top: 5em;
}
h2,
h3 {
font-size: 1.25em;
}
h4,
h5,
h6 {
font-size: 1em;
}
section {
padding-top: 1rem;
margin-top: -1rem;
}
section.subsec > h6 {
margin-top: 2em;
}
section.subsec > h6 > a {
color: var(--color-subsection-link);
}
section .spec-secid {
margin-right: 1ex;
}
@media (min-width: 720px) {
section .spec-secid {
position: absolute;
right: 100%;
text-align: right;
white-space: nowrap;
}
}
footer {
font-size: 75%;
opacity: 0.5;
text-align: center;
margin-top: 12rem;
}
/* Table of contents */
.spec-toc {
margin: 1rem 0 3rem;
}
.spec-toc .title {
content: "Contents";
display: block;
font-weight: bold;
margin: 5em 0 1em;
}
.spec-toc .spec-secid {
margin-right: 1ex;
}
.spec-toc ol {
list-style: none;
padding-left: 0;
margin-top: 0;
margin-bottom: 0;
}
.spec-toc ol ol {
list-style: none;
padding-left: 2ex;
margin-bottom: 0.25em;
}
.spec-toc li {
position: relative;
padding: 5px 0 0 30px;
margin: -5px 0 0 -30px;
}
.spec-toc a {
color: var(--color-toc-link);
}
.spec-toc a:hover {
text-decoration: none;
}
.spec-toc a .spec-secid {
color: var(--color-toc-id);
}
.spec-toc a:hover .spec-secid {
text-decoration: underline;
}
.spec-toc .toggle {
display: none;
}
.spec-toc .toggle + label {
cursor: pointer;
left: 6px;
opacity: 1;
padding: 5px 6px 5px 7px;
position: absolute;
top: 6px;
transform: rotate(0deg);
transition: all 0.18s ease-in-out;
}
.spec-toc .toggle + label:after {
border-color: transparent transparent transparent var(--color-toggle-border);
border-style: solid;
border-width: 6px 0 6px 7px;
content: " ";
display: block;
height: 0;
width: 0;
}
@media (pointer: fine) {
.spec-toc .toggle + label {
left: 10px;
padding: 3px 5px 3px 6px;
top: 8px;
}
}
.spec-toc .toggle:checked + label {
transform: rotate(90deg);
}
@media (hover: hover) {
.spec-toc li:not(:hover) > .toggle:checked + label {
opacity: 0;
}
}
.spec-toc .toggle:not(:checked) ~ ol {
max-height: 0;
overflow: hidden;
margin: 0;
}
/* Sidebar */
.spec-sidebar-toggle {
display: none;
}
.spec-sidebar-toggle + label > .spec-sidebar-button {
position: fixed;
right: 0;
top: 0;
padding: 10px 15px;
font-size: 30px;
color: var(--color-sidebar-toggle-button);
z-index: 2;
cursor: pointer;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.spec-sidebar-toggle:checked + label:after {
content: "";
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 0;
}
.spec-sidebar {
display: none;
position: fixed;
right: 0;
top: 0;
width: min(320px, calc(100vw - 48px));
font-size: 14px;
line-height: 1.75;
overflow-y: scroll;
height: 100%;
padding: 0 0 5rem 30px;
box-sizing: border-box;
background: var(--color-sidebar-background);
box-shadow: inset 1px 0 var(--color-sidebar-shadow-inset),
-4px 0 8px -2px var(--color-sidebar-shadow);
overscroll-behavior: contain;
}
.spec-sidebar {
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.spec-sidebar-toggle:checked ~ .spec-sidebar {
display: block;
}
.spec-sidebar .viewing > a:after {
color: var(--color-sidebar-viewing-link);
content: "\2022";
margin-left: 1ex;
}
@media (min-width: 1220px) {
.spec-sidebar-toggle + label {
display: none;
}
.spec-sidebar {
display: block;
box-shadow: inset 1px 0 var(--color-sidebar-shadow-inset),
inset 4px 0 8px -2px var(--color-sidebar-large-shadow) ;
}
body {
padding-right: 345px;
}
}
/* Notes */
.spec-note {
background: var(--color-spec-note-background);
border-left: solid 4px var(--color-spec-note-border);
margin: 1rem -1rem;
min-width: 70vw;
padding: 8px 1rem 12px calc(1rem - 4px);
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
}
@media (min-width: 720px) {
.spec-note {
min-width: 416px;
}
}
.spec-note > a:first-child {
color: var(--color-spec-note-first-link);
display: block;
font: italic 11pt/18pt var(--font-family);
opacity: 0.6;
user-select: none;
}
/* Todos */
.spec-todo {
color: var(--color-spec-todo);
margin: 1em 0 1em 5em;
min-height: 1em;
}
.spec-todo::before {
content: "todo";
display: block;
float: left;
margin-left: -5em;
text-transform: uppercase;
}
/* Index table */
.spec-index ol {
list-style-type: none;
margin: 0 0 0 var(--indent);
padding: 0;
column-width: 210px;
column-gap: var(--indent);
}
.spec-index ol li {
width: min-content;
white-space: nowrap;
}
/* Code */
pre,
code {
font-family: var(--font-family-monospace);
font-size: var(--mono-font-size);
font-weight: inherit;
}
code {
background: var(--color-code-background);
margin: -2px -1px;
padding: 3px 3px;
white-space: pre-wrap;
}
pre > code {
background: none;
font-weight: inherit;
margin: 0;
padding: 0;
white-space: pre;
}
pre {
background: var(--color-pre-background);
border-left: solid 4px var(--color-pre-border);
margin: 1rem -1rem;
min-width: 70vw;
padding: 12px 1rem 12px calc(1rem - 4px);
width: -moz-fit-content;
width: -webkit-fit-content;
width: fit-content;
max-width: calc(100vw - 2rem);
overflow-y: auto;
}
@media (min-width: 720px) {
pre {
min-width: 40ch;
}
}
.spec-example {
background: var(--color-spec-example);
border-left: solid 4px var(--color-spec-example-border);
padding-top: 8px;
}
.spec-counter-example {
background: var(--color-spec-counter-example);
border-left: solid 4px var(--color-spec-counter-border);
padding-top: 8px;
}
.spec-example > a,
.spec-counter-example > a {
display: block;
font: italic 11pt/18pt var(--font-family);
opacity: 0.6;
user-select: none;
}
.spec-counter-example > a {
color: var(--color-spec-counter-example-link);
}
/* Tables */
table {
border-collapse: collapse;
}
th {
background-color: var(--color-table-header);
}
td,
th {
border: 1px solid var(--color-table-header-border);
padding: 0.4em;
vertical-align: baseline;
}
/* Lists */
ol,
ul {
padding-left: var(--list-indent);
}
li > ol,
li > ul {
margin-top: 0.25em;
margin-bottom: 0.5em;
}
li + li {
margin-top: 0.25em;
}
li.task {
list-style-type: none;
position: relative;
}
li.task > input:first-child {
margin-left: 0;
position: absolute;
transform: translateX(calc(-100% - 1ch));
}
/* Edits */
ins {
background-color: var(--color-inserts-background);
text-decoration: none;
}
del {
background-color: var(--color-deletions-background);
}
.spec-added,
.spec-removed {
border-left: 4px solid;
margin-left: -18px;
padding-left: 14px;
}
.spec-added {
border-color: var(--color-spec-added-border);
}
.spec-removed {
border-color: var(--color-spec-removed-border);
text-decoration: line-through;
}
/* Values */
.spec-keyword {
font-weight: bold;
}
.spec-string {
font-family: var(--font-family-monospace);
font-size: 85%;
white-space: pre;
}
var {
font-style: italic;
}
*[data-name] {
transition: 0.15s background ease-out;
border-radius: 2px;
padding: 0 3px;
margin: 0 -3px;
}
/* Grammar semantics, algorithms and calls */
.spec-semantic,
.spec-algo {
margin: 1rem 0 1rem var(--dfn-indent);
}
.spec-semantic > .spec-nt::after,
.spec-algo > .spec-call:first-child::after {
content: ":";
font-style: normal;
font-weight: bold;
margin-left: 1ex;
}
.spec-semantic ol,
.spec-semantic ol ol ol ol,
.spec-algo ol,
.spec-algo ol ol ol ol {
list-style-type: decimal;
}
.spec-semantic ol ol,
.spec-semantic ol ol ol ol ol,
.spec-algo ol ol,
.spec-algo ol ol ol ol ol {
list-style-type: lower-alpha;
}
.spec-semantic ol ol ol,
.spec-semantic ol ol ol ol ol ol,
.spec-algo ol ol ol,
.spec-algo ol ol ol ol ol ol {
list-style-type: lower-roman;
}
.spec-call > a {
color: inherit;
}
/* Grammar productions */
.spec-production {
margin: 1rem 0 1rem var(--dfn-indent);
}
.spec-production > .spec-nt::after {
content: ":";
font-style: normal;
font-weight: bold;
margin: 0 1ex;
}
.spec-semantic.d2 > .spec-nt::after,
.spec-production.d2 > .spec-nt::after {
content: "::";
}
.spec-semantic.d3 > .spec-nt::after,
.spec-production.d3 > .spec-nt::after {
content: ":::";
}
.spec-production > .spec-rhs {
line-height: 1.1;
margin: 0.25em 0 0.5em calc(2 * var(--indent));
text-indent: calc(-1 * var(--indent));
}
.spec-semantic > .spec-rhs {
display: inline-block;
text-indent: calc(-1 * var(--indent));
margin-left: calc(1ex + var(--indent));
}
.spec-rhs > * {
text-indent: 0;
}
.spec-oneof {
display: inline;
}
.spec-oneof::before {
content: "one of";
font-style: normal;
font-weight: bold;
}
.spec-oneof-grid {
max-width: calc(100vw - 2rem);
overflow: auto;
margin: -1ex -1rem;
padding: 1ex 1rem;
}
.spec-oneof-grid > table {
margin-left: var(--indent);
}
.spec-oneof .spec-rhs {
border: none;
margin: 0;
padding: 0 0 0 1rem;
vertical-align: baseline;
white-space: pre;
}
.spec-oneof .spec-rhs:first-child {
padding: 0;
}
.spec-rhs .spec-constrained:not(:first-child),
.spec-rhs .spec-quantified:not(:first-child),
.spec-rhs .spec-nt:not(:first-child),
.spec-rhs .spec-t:not(:first-child),
.spec-rhs .spec-rx:not(:first-child),
.spec-rhs .spec-prose:not(:first-child),
.spec-rhs .spec-empty:not(:first-child),
.spec-rhs .spec-lookahead:not(:first-child) {
margin-left: 1ex;
display: inline-block;
}
.spec-condition {
font-size: 85%;
}
.spec-condition::before {
content: "[if ";
}
.spec-condition.not::before {
content: "[if not ";
}
.spec-condition::after {
content: "]";
}
.spec-empty,
.spec-prose {
color: var(--color-spec-prose);
}
.spec-nt {
font-style: italic;
}
.spec-nt > a {
color: inherit;
}
.spec-quantifiers,
.spec-params {
font-size: 65%;
font-style: normal;
vertical-align: sub;
}
.spec-quantifier.list {
color: var(--color-spec-quantifier-list);
}
.spec-quantifier.optional {
color: var(--color-spec-quantifier-optional);
}
.spec-params,
.spec-condition {
color: var(--color-spec-condition);
}
.spec-params::before {
content: "[";
}
.spec-params::after {
content: "]";
}
.spec-quantifier:not(:last-child)::after,
.spec-param:not(:last-child)::after {
color: var(--color-spec-param);
content: ", ";
}
.spec-param.conditional::before {
content: "?";
}
.spec-param.negated::before {
content: "!";
}
.spec-t,
.spec-rx {
color: var(--color-spec-rx);
font-family: var(--font-family-monospace);
font-weight: bold;
}
.spec-butnot::before {
color: var(--color-grey);
content: "but not";
font-family: var(--font-family);
font-weight: normal;
margin-right: 1ex;
}
.spec-butnot > *:not(:first-child)::before {
color: var(--color-grey);
content: "or";
font-family: var(--font-family);
font-weight: normal;
margin-right: 1ex;
}
.spec-rhs .spec-oneof::before,
.spec-rhs .spec-butnot::before {
margin-left: 1ex;
}
.spec-lookahead > * {
margin: 0 ;
}
.spec-lookahead > *:not(:first-child)::before {
color: var(--color-grey);
content: ", ";
font-family: var(--font-family);
font-style: normal;
font-weight: normal;
}
.spec-lookahead::before {
color: var(--color-grey);
content: "[lookahead = ";
font-family: var(--font-family);
font-style: normal;
font-weight: normal;
}
.spec-lookahead.not::before {
content: "[lookahead \2260 ";
}
.spec-lookahead.set::before {
content: "[lookahead \2208 {";
margin-right: 0;
}
.spec-lookahead.set.not::before {
content: "[lookahead \2209 {";
}
.spec-lookahead.ntset::before {
content: "[lookahead \2208 ";
margin-right: 0;
}
.spec-lookahead.ntset.not::before {
content: "[lookahead \2209 ";
}
.spec-lookahead::after {
color: var(--color-grey);
content: "]";
}
.spec-lookahead.set::after {
content: "}]";
}
/* Prism color scheme */
code[class*="language-"],
pre[class*="language-"] {
color: var(--color-prism-foreground);
background: none;
text-shadow: 0 1px var(--color-prism-text-shadow);
font-family: var(--font-family-monospace);
font-size: 1em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: var(--color-prism-background);
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: var(--color-prism-background);
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: 0.5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: var(--color-prism-block-background);
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: 0.1em;
border-radius: 0.3em;
white-space: normal;
}
.token.atrule,
.token.attr-value,
.token.keyword,
.token.property,
.token.selector,
.token.attr-name,
.token.builtin,
.token.entity,
.token.url,
.token.inserted {
color: var(--color-token-inserted);
background: none;
}
.token.tag,
.token.boolean,
.token.number,
.token.string,
.token.char,
.token.constant,
.token.symbol,
.token.regex,
.token.important,
.token.variable,
.token.function,
.token.class-name,
.token.deleted {
color: var(--color-token-deleted);
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata,
.token.description {
color: inherit;
opacity: 0.3;
}
.token.punctuation {
color: inherit;
opacity: 0.5;
}
.token.operator,
.token.namespace {
color: inherit;
opacity: 0.7;
}