Skip to content

Commit 97178c6

Browse files
committed
Rewrite all guides
* add twoslash * add mentions of micromark * modernize jsdoc, jsx use * rewrite out of date “Create an editor”, using esbuild and react * change plugins highlighted in “Intro to unified” * rewrite “Narrow node TypeScript”, with new `Nodes` unions
1 parent 0e18b82 commit 97178c6

29 files changed

+1424
-1061
lines changed

.remarkrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const naturalLanguage = unified().use([
2525
retextEnglish,
2626
retextPresetWooorm,
2727
[retextEquality, {ignore: ['whitespace']}],
28-
retextPassive,
28+
[retextPassive, {ignore: ['hidden']}],
2929
[retextProfanities, {sureness: 1}],
3030
[retextReadability, {age: 18, minWords: 8}],
3131
[retextSimplify, {ignore: ['function', 'interface', 'maintain', 'type']}],

asset/browser.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/// <reference lib="dom" />
2+
3+
/* eslint-env browser */
4+
5+
import {computePosition, shift} from '@floating-ui/dom'
6+
7+
if ('paintWorklet' in CSS) {
8+
// @ts-expect-error: CSS is not yet fully typed.
9+
CSS.paintWorklet.addModule('https://esm.sh/css-houdini-squircle@0.3?bundle')
10+
}
11+
12+
const popoverTargets = /** @type {Array<HTMLElement>} */ (
13+
Array.from(document.querySelectorAll('.rehype-twoslash-popover-target'))
14+
)
15+
16+
for (const popoverTarget of popoverTargets) {
17+
/** @type {NodeJS.Timeout | number} */
18+
let timeout = 0
19+
20+
popoverTarget.addEventListener('click', function () {
21+
popoverShow(popoverTarget)
22+
})
23+
24+
popoverTarget.addEventListener('mouseenter', function () {
25+
clearTimeout(timeout)
26+
timeout = setTimeout(function () {
27+
popoverShow(popoverTarget)
28+
}, 300)
29+
})
30+
31+
popoverTarget.addEventListener('mouseleave', function () {
32+
clearTimeout(timeout)
33+
})
34+
35+
if (popoverTarget.classList.contains('rehype-twoslash-autoshow')) {
36+
popoverShow(popoverTarget)
37+
}
38+
}
39+
40+
/**
41+
* @param {HTMLElement} popoverTarget
42+
* Popover target.
43+
* @returns {undefined}
44+
* Nothing.
45+
*/
46+
function popoverShow(popoverTarget) {
47+
const id = popoverTarget.dataset.popoverTarget
48+
if (!id) return
49+
const popover = document.getElementById(id)
50+
if (!popover) return
51+
52+
popover.showPopover()
53+
54+
computePosition(popoverTarget, popover, {
55+
placement: 'bottom',
56+
middleware: [shift({padding: 5})]
57+
}).then(
58+
/**
59+
* @param {{x: number, y: number}} value
60+
*/
61+
function (value) {
62+
popover.style.left = value.x + 'px'
63+
popover.style.top = value.y + 'px'
64+
}
65+
)
66+
}

asset/dark.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,19 @@ a.tag:focus .count {
163163
border-bottom-color: var(--gray-6);
164164
}
165165

166+
.highlight:is(:hover, :focus-within) .rehype-twoslash-popover-target {
167+
background-color: var(--gray-5);
168+
}
169+
170+
.rehype-twoslash-popover {
171+
background-color: var(--gray-9);
172+
border-color: var(--gray-7);
173+
}
174+
175+
.rehype-twoslash-popover-description {
176+
background-color: var(--gray-9);
177+
}
178+
166179
.screen {
167180
background-image: linear-gradient(150deg, #0366d6 15%, #24292e 85%);
168181
}

asset/houdini.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

asset/image/unified-overview.png

-912 KB
Binary file not shown.

asset/index.css

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,13 @@ abbr {
249249
}
250250

251251
.mdast .hl,
252+
.micromark .hl,
252253
.remark .hl,
253254
.content .mdast:hover .hl,
255+
.content .micromark:hover .hl,
254256
.content .remark:hover .hl,
255257
.content .mdast:focus .hl,
258+
.content .micromark:focus .hl,
256259
.content .remark:focus .hl {
257260
color: hsl(0deg 97% 43%);
258261
}
@@ -827,6 +830,56 @@ a.tag:focus .count {
827830
border-bottom-color: var(--gray-3);
828831
}
829832

833+
.rehype-twoslash-completion-deprecated {
834+
opacity: 0.5;
835+
}
836+
837+
.rehype-twoslash-popover-target {
838+
cursor: default;
839+
}
840+
841+
.highlight:is(:hover, :focus-within) .rehype-twoslash-popover-target {
842+
background-color: var(--gray-2);
843+
}
844+
845+
/* Wavy underline for errors. */
846+
.rehype-twoslash-error-target {
847+
background-repeat: repeat-x;
848+
background-position: bottom left;
849+
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 6 3" enable-background="new 0 0 6 3" height="3" width="6"><g fill="%23c94824"><polygon points="5.5,0 2.5,3 1.1,3 4.1,0"/><polygon points="4,0 6,2 6,0.6 5.4,0"/><polygon points="0,2 1,3 2.4,3 0,0.6"/></g></svg>');
850+
}
851+
852+
/* The content that will be shown in the tooltip. */
853+
.rehype-twoslash-popover {
854+
position: absolute;
855+
max-width: calc(45 * (1em + 1ex));
856+
padding: calc(0.5 * (1em + 1ex));
857+
margin: 0;
858+
background-color: var(--gray-0);
859+
border: 1px solid var(--gray-2);
860+
border-radius: 3px;
861+
}
862+
863+
/* No padding if we have a padded code block (and perhaps more blocks) */
864+
.rehype-twoslash-popover:has(.rehype-twoslash-popover-code) {
865+
padding: 0;
866+
}
867+
868+
.rehype-twoslash-popover-code {
869+
/* Overwrite `.content pre` */
870+
margin: 0 !important;
871+
}
872+
873+
.rehype-twoslash-popover-code > code {
874+
mask-image: none;
875+
border-radius: 0;
876+
}
877+
878+
.rehype-twoslash-popover-description {
879+
background-color: var(--gray-0);
880+
padding: 0 calc(2 * (1em + 1ex));
881+
}
882+
830883
@media (width <= 48em) {
831884
.x-show-l {
832885
display: none;

dictionary.txt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// Jargon
22
API
3+
CLI
4+
XSS
35
attacher
46
bundler
5-
CLI
67
debounced
8+
esbuild
79
hacky
810
linter
911
math
@@ -20,31 +22,33 @@ stdout
2022
stringifier
2123
stringify
2224
syntaxes
23-
XSS
25+
whitespace
2426

2527
// Names, products, etc.
2628
BundlePhobia
27-
browserify
29+
CDN
2830
CommonMark
2931
DOM
32+
Deno
3033
GFM
3134
HSL
32-
hast
3335
JSDoc
3436
JSON
3537
JSX
36-
MacBook
3738
MDX
38-
mdast
39+
MacBook
3940
Node.js
41+
Otander
42+
Preact
43+
hast
44+
mdast
4045
nlcst
4146
npm
42-
Otander
4347
rehype
4448
remark
4549
retext
46-
unist
4750
unified
51+
unist
4852
vfile
4953
xast
5054
xo

doc/learn/build-a-syntax-tree.md

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
---
2+
authorGithub: ChristianMurphy
3+
author: Christian Murphy
4+
description: How to build content with syntax trees
25
group: recipe
36
index: 8
4-
title: Build a syntax tree
5-
description: How to build content with syntax trees
7+
modified: 2024-08-02
8+
published: 2020-06-09
69
tags:
7-
- unist
8-
- mdast
10+
- esast
911
- hast
12+
- mdast
13+
- nlcst
14+
- unist
1015
- xast
11-
author: Christian Murphy
12-
authorGithub: ChristianMurphy
13-
published: 2020-06-09
14-
modified: 2020-06-15
16+
title: Build a syntax tree
1517
---
1618

1719
## How to build a syntax tree
@@ -28,10 +30,11 @@ The most basic way to create a tree is with plain object and arrays.
2830
To prevent type errors, this can be checked with the types for the given syntax
2931
tree language, in this case mdast:
3032

31-
```ts
33+
```ts twoslash
3234
import type {Root} from 'mdast'
3335

34-
// Note the `: Root` is a TypeScript annotation. Remove it (and the import) for plain JavaScript.
36+
// Note the `: Root` is a TypeScript annotation.
37+
// For plain JavaScript, remove it (and the import).
3538
const mdast: Root = {
3639
type: 'root',
3740
children: [
@@ -54,9 +57,14 @@ It’s also possible to build trees with [`unist-builder`][u].
5457
It allows a more concise, “hyperscript” like syntax (which is also like
5558
`React.createElement`):
5659

57-
```js
60+
```js twoslash
61+
/**
62+
* @import {Root} from 'mdast'
63+
*/
64+
5865
import {u} from 'unist-builder'
5966

67+
/** @type {Root} */
6068
const mdast = u('root', [
6169
u('paragraph', [
6270
u('text', 'example')
@@ -68,7 +76,9 @@ const mdast = u('root', [
6876

6977
When working with hast (HTML), [`hastscript`][h] can be used.
7078

71-
```js
79+
```js twoslash
80+
/// <reference types="node" />
81+
// ---cut---
7282
import {h, s} from 'hastscript'
7383

7484
console.log(
@@ -81,7 +91,7 @@ console.log(
8191

8292
// SVG:
8393
console.log(
84-
s('svg', {viewbox: '0 0 500 500', xmlns: 'http://www.w3.org/2000/svg'}, [
94+
s('svg', {viewBox: '0 0 500 500', xmlns: 'http://www.w3.org/2000/svg'}, [
8595
s('title', 'SVG `<circle>` element'),
8696
s('circle', {cx: 120, cy: 120, r: 100})
8797
])
@@ -90,9 +100,10 @@ console.log(
90100

91101
`hastscript` can also be used as a JSX configuration comment:
92102

93-
```jsx
94-
/** @jsx h @jsxFrag null */
95-
import {h} from 'hastscript'
103+
```tsx twoslash
104+
/// <reference types="node" />
105+
// ---cut---
106+
/** @jsxImportSource hastscript */
96107

97108
console.log(
98109
<form method="POST">
@@ -108,7 +119,9 @@ console.log(
108119
When working with xast (XML), [`xastscript`][x]
109120
can be used.
110121

111-
```js
122+
```js twoslash
123+
/// <reference types="node" />
124+
// ---cut---
112125
import {x} from 'xastscript'
113126

114127
console.log(
@@ -122,9 +135,10 @@ console.log(
122135

123136
`xastscript` can also be used as a JSX configuration comment:
124137

125-
```jsx
126-
/** @jsx x @jsxFrag null */
127-
import {x} from 'xastscript'
138+
```tsx twoslash
139+
/// <reference types="node" />
140+
// ---cut---
141+
/** @jsxImportSource xastscript */
128142

129143
console.log(
130144
<album id={123}>

0 commit comments

Comments
 (0)