Skip to content

Commit 405e623

Browse files
Enhancing styling with Pico CSS and adding some features (#1672)
* Attempt to make the spec look stylish * Code block styling * Adding Pico CSS for better styling * Fixing ToC format & highlighting * Fixing code block & ToC format * removing extra customizations * Rely more on pico * fixing padding and margins * Update the padding to work with smaller screens * better color for links * fixing horizontal scroll & editing links style * Less indentation in the table of contents * Try a new color theme based on the code highlighting theme * Cleanup some code styling --------- Co-authored-by: Jason Desrosiers <jdesrosi@gmail.com>
1 parent 59a7e1c commit 405e623

9 files changed

Lines changed: 323 additions & 99 deletions

remark/remark-code-titles.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const remarkNumberHeadings = () => (tree) => {
1515
}
1616

1717
let title = "";
18-
const titleClasses = ["remark-code-title"];
18+
const titleClasses = [];
1919

2020
const language = codeNode.lang ?? "";
2121
if (language.toLowerCase() === "jsonschema") {
@@ -43,23 +43,34 @@ const remarkNumberHeadings = () => (tree) => {
4343

4444
const containerChildren = [];
4545
if (title) {
46-
const titleNode = div([text(title)], { className: titleClasses });
46+
const titleNode = figcaption([text(title)], { className: titleClasses });
4747
containerChildren.push(titleNode);
4848
}
4949
containerChildren.push(codeNode);
5050

51-
const wrappedCodeNode = div(containerChildren, { className: ["remark-code-container"] });
51+
const wrappedCodeNode = figure(containerChildren);
5252

5353
parent.children.splice(index, 1, wrappedCodeNode);
5454
});
5555
};
5656

57-
const div = (children, properties) => {
57+
const figure = (children, properties) => {
5858
return {
5959
type: "container",
6060
children,
6161
data: {
62-
hName: "div",
62+
hName: "figure",
63+
hProperties: properties
64+
}
65+
};
66+
};
67+
68+
const figcaption = (children, properties) => {
69+
return {
70+
type: "container",
71+
children,
72+
data: {
73+
hName: "figcaption",
6374
hProperties: properties
6475
}
6576
};

remark/remark-rfc2119.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { text } from "mdast-builder";
2+
import { visit } from "unist-util-visit";
3+
4+
5+
/**
6+
* RFC 2119 / RFC 8174 keywords
7+
* Order matters: longer phrases first
8+
*/
9+
const KEYWORDS = [
10+
"MUST NOT",
11+
"NOT REQUIRED",
12+
"SHALL NOT",
13+
"SHOULD NOT",
14+
"NOT RECOMMENDED",
15+
"MUST",
16+
"REQUIRED",
17+
"SHALL",
18+
"SHOULD",
19+
"RECOMMENDED",
20+
"MAY",
21+
"OPTIONAL"
22+
];
23+
24+
const KEYWORD_REGEX = new RegExp(`(?:${KEYWORDS.map((k) => k.replace(" ", "\\s")).join("|")})`, "gm");
25+
26+
const skipNodes = new Set(["code", "inlineCode", "link", "definition", "html"]);
27+
28+
export default function remarkRfc2119() {
29+
return (tree) => {
30+
visit(tree, "text", (node, index, parent) => {
31+
// Do not touch code, inlineCode, links, or HTML
32+
if (skipNodes.has(parent.type)) {
33+
return;
34+
}
35+
36+
const value = node.value;
37+
let match;
38+
let lastIndex = 0;
39+
const children = [];
40+
41+
KEYWORD_REGEX.lastIndex = 0;
42+
43+
while ((match = KEYWORD_REGEX.exec(value)) !== null) {
44+
const [keyword] = match;
45+
const start = match.index;
46+
const end = start + keyword.length;
47+
48+
if (start > lastIndex) {
49+
children.push(text(value.slice(lastIndex, start)));
50+
}
51+
52+
const keywordNode = text(keyword);
53+
keywordNode.data = {
54+
hName: "span",
55+
hProperties: {
56+
className: ["rfc2119", keyword.toLowerCase().replace(/\s+/g, "-")]
57+
}
58+
};
59+
children.push(keywordNode);
60+
61+
lastIndex = end;
62+
}
63+
64+
if (children.length === 0) {
65+
return;
66+
}
67+
68+
if (lastIndex < value.length) {
69+
children.push(text(value.slice(lastIndex)));
70+
}
71+
72+
parent.children.splice(index, 1, ...children);
73+
});
74+
};
75+
}

remark/remark-table-of-contents.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ const remarkTableOfContents = (options) => (tree, file) => {
2525
const headingText = nodeToString(headingNode);
2626

2727
if (headingText === options.heading) {
28+
headingNode.data = {
29+
hProperties: {
30+
className: ["toc-heading"]
31+
}
32+
};
33+
tableOfContents.data = {
34+
hProperties: {
35+
className: ["toc"]
36+
}
37+
};
38+
2839
insertTableOfContents = () => {
2940
parent.children.splice(index + 1, 0, tableOfContents);
3041
};
@@ -37,7 +48,7 @@ const remarkTableOfContents = (options) => (tree, file) => {
3748
while (headingNode.depth > currentDepth) {
3849
const newList = list("unordered");
3950
listStack.push(newList);
40-
currentList.children.push(newList);
51+
currentList.children.push(listItem(newList));
4152
currentList = newList;
4253
currentDepth++;
4354
}

specs/.remarkrc-build.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,21 @@ export default {
1818
[rehypeHighlightCodeLines, { showLineNumbers: true }],
1919
rehypeLinkTransformer,
2020
[rehypeDocument, {
21-
css: [
22-
"https://cdn.jsdelivr.net/npm/water.css@2/out/dark.css",
23-
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/github-dark-dimmed.min.css"
21+
link: [
22+
{
23+
rel: "stylesheet",
24+
href: "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css"
25+
},
26+
{
27+
rel: "stylesheet",
28+
href: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/github-dark-dimmed.min.css",
29+
media: "(prefers-color-scheme: dark)"
30+
},
31+
{
32+
rel: "stylesheet",
33+
href: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/github.min.css",
34+
media: "(prefers-color-scheme: light)"
35+
}
2436
],
2537
style: readFileSync(resolve(import.meta.dirname, "spec.css"), "utf8")
2638
}],

specs/.remarkrc-specs.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import remarkCodeTitles from "../remark/remark-code-titles.js";
55
import remarkHeadings from "../remark/remark-headings.js";
66
import remarkReferenceLinks from "../remark/remark-reference-links.js";
77
import remarkTableOfContents from "../remark/remark-table-of-contents.js";
8+
import remarkRfc2119 from "../remark/remark-rfc2119.js";
89

910

1011
export default {
@@ -37,6 +38,7 @@ export default {
3738
]
3839
}],
3940
remarkFlexibleContainers,
40-
remarkCodeTitles
41+
remarkCodeTitles,
42+
remarkRfc2119
4143
]
4244
};

specs/jsonschema-core.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ In the cases where optimizations are enabled and a schema containing a
14841484
non-resolvable reference would be skipped, as in the example below, behavior is
14851485
implementation-defined.
14861486

1487-
```json
1487+
```jsonschema
14881488
{
14891489
"anyOf": [
14901490
true,
@@ -1518,7 +1518,7 @@ downloadable JSON Schema using the link relation "describedby", as defined by
15181518
In HTTP, such links can be attached to any response using the [Link
15191519
header][rfc8288]. An example of such a header would be:
15201520

1521-
```
1521+
```http noLineNumbers
15221522
Link: <https://example.com/my-hyper-schema>; rel="describedby"
15231523
```
15241524

@@ -1541,7 +1541,7 @@ implementation or software product. Since symbols are listed in decreasing order
15411541
of significance, the JSON Schema library name/version should precede the more
15421542
generic HTTP library name (if any). For example:
15431543

1544-
```
1544+
```http noLineNumbers
15451545
User-Agent: product-name/5.4.1 so-cool-json-schema/1.0.2 curl/7.43.0
15461546
```
15471547

@@ -1969,7 +1969,7 @@ which evaluation passes to reach the schema object that produced a specific
19691969
result. The value MUST be expressed as a JSON Pointer, and it MUST include any
19701970
by-reference applicators such as `$ref` or `$dynamicRef`.
19711971

1972-
```
1972+
```text noLineNumbers
19731973
/properties/width/$ref/allOf/1
19741974
```
19751975

@@ -1986,7 +1986,7 @@ Pointer fragment indicating the subschema that produced a result. In contrast
19861986
with the evaluation path, the schema location MUST NOT include by-reference
19871987
applicators such as `$ref` or `$dynamicRef`.
19881988

1989-
```
1989+
```text noLineNumbers
19901990
https://example.com/schemas/common#/$defs/allOf/1
19911991
```
19921992

specs/proposals/propertyDependencies.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ The `dependentSchemas` keyword is very close to what is needed except it checks
5454
for the presence of a property rather than it's value. The chosen solution is to
5555
build on that concept to solve this problem.
5656

57-
```json
57+
```jsonschema
5858
{
5959
"propertyDependencies": {
6060
"foo": {
@@ -66,7 +66,7 @@ build on that concept to solve this problem.
6666

6767
The validation result is equivalent to the following schema.
6868

69-
```json
69+
```jsonschema
7070
{
7171
"if": {
7272
"properties": {
@@ -115,7 +115,7 @@ vocabulary](../jsonschema-core.md#applicators).
115115
`https://json-schema.org/<version>/<release>/meta/applicator` at
116116
`/properties/propertyDependencies`:
117117

118-
```json
118+
```jsonschema
119119
{
120120
"type": "object",
121121
"additionalProperties": {

specs/proposals/vocabularies.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ booleans as values. This keyword only has meaning within a meta-schema. A
8282
meta-schema which includes a vocabulary's URI in its `$vocabulary` keyword is
8383
said to "include" that vocabulary.
8484

85-
```jsonc
85+
```jsonschema
8686
{
8787
"$schema": "https://example.org/draft/next/schema",
8888
"$id": "https://example.org/schema",
@@ -132,7 +132,7 @@ schemas.) To facilitate this extra validation, when a vocabulary schema is
132132
provided, any meta-schema which includes the vocabulary should also contain a
133133
reference (via `$ref`) to the vocabulary schema's `$id` value.
134134

135-
```jsonc
135+
```jsonschema
136136
{
137137
"$schema": "https://example.org/draft/next/schema",
138138
"$id": "https://example.org/schema",
@@ -156,7 +156,7 @@ the meta-schema and added to vocabulary schemas to which the meta-schema will
156156
contain references. In this way, the meta-schema's functionality remains the
157157
same.
158158

159-
```json
159+
```jsonschema
160160
{
161161
"$schema": "https://json-schema.org/draft/next/schema",
162162
"$id": "https://json-schema.org/draft/next/schema",
@@ -246,7 +246,7 @@ For example
246246
2. The following subschema will be added to the Applicator Vocabulary schema,
247247
`https://json-schema.org/<version>/<release>/meta/applicator`, at
248248
`/properties/{keyword}`:
249-
```jsonc
249+
```jsonschema
250250
{
251251
// keyword schema
252252
}

0 commit comments

Comments
 (0)