rshow 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +15002 -668
- package/package.json +2 -1
- package/skills/rshow/SKILL.md +13 -4
- package/skills/rshow/reference/cli.md +8 -6
- package/skills/rshow/reference/dashboard.md +5 -5
- package/skills/rshow/reference/page-contract.md +2 -1
- package/skills/rshow/reference/pages.md +7 -7
- package/skills/rshow/reference/poster.md +5 -5
- package/skills/rshow/reference/project-page.md +5 -5
- package/skills/rshow/reference/reports.md +10 -6
- package/skills/rshow/reference/sketch.md +5 -5
- package/skills/rshow/reference/terminal.md +5 -5
- package/skills/rshow-slides/SKILL.md +11 -6
- package/skills/rshow-slides/reference/layouts.md +15 -0
- package/themes/default/deck.js +86 -4
- package/themes/default/example/index.html +19 -2
- package/themes/default/example/report.html +17 -10
- package/themes/default/fonts/katex/KaTeX_AMS-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Main-Bold.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Main-Italic.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Main-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Math-Italic.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Script-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Size1-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Size2-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Size3-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Size4-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/themes/default/fonts/katex/LICENSE +21 -0
- package/themes/default/math.css +46 -0
- package/themes/default/math.js +58 -0
- package/themes/default/report.css +15 -6
- package/themes/default/theme.json +7 -0
- package/worker/index.js +118 -46
- package/worker/migrations/0005_version_counters.sql +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rshow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Publish static artifacts to rshow",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://rslib.github.io/rshow",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^26.6.6",
|
|
46
46
|
"esbuild": "0.28.2",
|
|
47
|
+
"katex": "0.19.1",
|
|
47
48
|
"rshow-shared": "*",
|
|
48
49
|
"typescript": "^5.9.3"
|
|
49
50
|
}
|
package/skills/rshow/SKILL.md
CHANGED
|
@@ -20,7 +20,7 @@ Copy this checklist into the reply and tick it as you go.
|
|
|
20
20
|
|
|
21
21
|
```text
|
|
22
22
|
- [ ] shape picked and outline or headings agreed
|
|
23
|
-
- [ ] page written, theme linked at
|
|
23
|
+
- [ ] page written, theme linked at `@latest`
|
|
24
24
|
- [ ] rshow check <dir> exits 0
|
|
25
25
|
- [ ] rshow preview <dir> looked at 360px wide and at desktop width
|
|
26
26
|
- [ ] audience confirmed with the person
|
|
@@ -30,7 +30,7 @@ Copy this checklist into the reply and tick it as you go.
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
1. Pick the shape and say it back in one sentence, such as a page, a report, a poster, a project page, a dashboard, a mockup, a sketch, a terminal page or a prerendered Astro or Vite site.
|
|
33
|
-
2. Write `index.html` in its own folder, link the theme at
|
|
33
|
+
2. Write `index.html` in its own folder, link the theme at `@latest` and keep every other path relative.
|
|
34
34
|
3. Run `rshow check <dir>`.
|
|
35
35
|
4. Fix every error, then run `rshow check` again until it exits 0.
|
|
36
36
|
5. Run `rshow preview <dir>` and open the printed `http://127.0.0.1:4321` link.
|
|
@@ -46,7 +46,10 @@ Copy this checklist into the reply and tick it as you go.
|
|
|
46
46
|
- Every path inside the artifact is relative, with no leading slash.
|
|
47
47
|
The only exceptions are `/_themes/...` and `/_data/...`.
|
|
48
48
|
- Link the theme, never copy it.
|
|
49
|
-
The stylesheet links and `mode.js` in the head all carry the same `<name
|
|
49
|
+
The stylesheet links and `mode.js` in the head all carry the same `<name>@latest`.
|
|
50
|
+
- Link `@latest`, so a theme fix reaches the page with no republish.
|
|
51
|
+
Write a number only when the person asks to freeze a page, such as a talk on the day it is given.
|
|
52
|
+
A page frozen on a number needs 8 or newer for math.
|
|
50
53
|
- The theme is the base, not a cage.
|
|
51
54
|
A page may carry one inline `<style>` block with its own classes and its own layouts when the content needs them.
|
|
52
55
|
Own CSS takes colour, type and space from the theme tokens with `var(--...)`, so light, dark, print and a theme swap keep working.
|
|
@@ -62,6 +65,10 @@ Copy this checklist into the reply and tick it as you go.
|
|
|
62
65
|
Never write `latest`.
|
|
63
66
|
- A report links `report.css` and `report.js` in place of `page.css`, and `mode.js` still goes in the head.
|
|
64
67
|
Read [reports](reference/reports.md) before you write one.
|
|
68
|
+
- Math is LaTeX in the text of an element with the class `math`, and the page links `math.css` and `math.js` for it.
|
|
69
|
+
A `div.math` is display math and any other element is inline.
|
|
70
|
+
A `$` in the prose is a price and is never read as math, so `$5` stays text.
|
|
71
|
+
Read [reports](reference/reports.md) for the markup an equation takes.
|
|
65
72
|
- The page reads at 360px wide.
|
|
66
73
|
Tables go inside `<div class="table">`.
|
|
67
74
|
- Nothing secret in a page, because anyone who holds the link can read the HTML source.
|
|
@@ -145,6 +152,8 @@ The short list above is a hard rule.
|
|
|
145
152
|
- Never publish a folder that holds `.env`, a key, a credential or customer data.
|
|
146
153
|
- Never publish a source tree, `node_modules` or a `dist` folder that still holds a draft.
|
|
147
154
|
- Never write the token into a page, a script, a log line, a commit or a chat message.
|
|
155
|
+
- Never fake math with Unicode subscripts, Greek letters in mono or an HTML `<sub>`.
|
|
156
|
+
Write the LaTeX in an element with the class `math` and link `math.css` and `math.js`.
|
|
148
157
|
- Never create a second artifact with a `-v2` slug.
|
|
149
158
|
Publish the same slug again.
|
|
150
|
-
- Never delete an artifact
|
|
159
|
+
- Never delete a version, a theme or an artifact, and never drop a share, unless the person asks for it.
|
|
@@ -25,7 +25,7 @@ This file is the whole surface, both config files and the exit codes.
|
|
|
25
25
|
| `rshow check <file-or-dir>` | apply the page contract to the files a publish would upload |
|
|
26
26
|
| `rshow preview <dir>` | serve a folder on `127.0.0.1` for a look, offline |
|
|
27
27
|
| `rshow publish <file-or-dir>` | upload a folder, or one file as `index.html`, as a new version |
|
|
28
|
-
| `rshow config [dir] [--offline]` | print the merged config as JSON, with `theme`
|
|
28
|
+
| `rshow config [dir] [--offline]` | print the merged config as JSON, with `theme` as `<name>@latest` and, with the network, `theme_resolved` as the version it resolves to |
|
|
29
29
|
| `rshow init --url <admin-url> --art <viewer-url>` | write the global config file, with `--theme` and `--force` |
|
|
30
30
|
| `rshow doctor [dir]` | check node, config, token, api, art, theme and skills, one `ok\|warn\|fail` line each |
|
|
31
31
|
| `rshow list` | list artifacts you own or that are shared with you, with `--project`, `--tag` and `--q` filters |
|
|
@@ -36,7 +36,7 @@ This file is the whole surface, both config files and the exit codes.
|
|
|
36
36
|
| `rshow tag <slug>` | add or remove tags on an artifact |
|
|
37
37
|
| `rshow handoff <slug>@v<n>` | write a design handoff folder from a published design |
|
|
38
38
|
| `rshow compare --against <dir>` | compare an implementation with that handoff folder |
|
|
39
|
-
| `rshow delete <slug> --yes` | delete an artifact |
|
|
39
|
+
| `rshow delete <slug> [--version n] [--force] --yes` | delete an artifact, or one version of it |
|
|
40
40
|
| `rshow theme new <name>` | write a preset folder that extends a built-in theme |
|
|
41
41
|
| `rshow theme check <dir>` | check a theme or preset folder against the token contract |
|
|
42
42
|
| `rshow theme preview <dir>` | build the theme, then serve its preview page on `127.0.0.1` |
|
|
@@ -77,7 +77,7 @@ They are never errors, because a person may have a reason.
|
|
|
77
77
|
`--no-style` skips all of them, and `--json` prints the findings as data.
|
|
78
78
|
|
|
79
79
|
`--offline` skips every request the check would make, so it works on a plane and it never waits on the host.
|
|
80
|
-
A published page that links `/_themes/<name>@<n>/` needs the network to confirm
|
|
80
|
+
A published page that links `/_themes/<name>@<n>/` or `/_themes/<name>@latest/` needs the network to confirm the theme exists, so a `--offline` run reports those links as unchecked rather than as a pass.
|
|
81
81
|
|
|
82
82
|
`rshow publish` runs the check first and stops while there is an error, so a page that fails the contract does not go live.
|
|
83
83
|
`--no-check` skips that step.
|
|
@@ -90,7 +90,7 @@ rshow preview <dir> [--theme <dir>] [--offline] [--no-reload] [--port 4321]
|
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
It serves `<dir>` on `127.0.0.1`, prints `http://127.0.0.1:<port>` and keeps running until you stop it.
|
|
93
|
-
It works offline: `/_themes/<name>@<n>/`
|
|
93
|
+
It works offline: `/_themes/<name>@<n>/` and `/_themes/<name>@latest/` come from `--theme` when that folder is the theme, then from the built-in theme on disk, and only then from the art URL in the config, which `--offline` turns off.
|
|
94
94
|
A page that uses `<artifact>/_data/<key>` gets a local store for the session, and the page reloads by itself when a file changes, which `--no-reload` turns off.
|
|
95
95
|
|
|
96
96
|
## publish
|
|
@@ -174,8 +174,10 @@ Set the tags and the project in `rshow.json` when they are a fact about the fold
|
|
|
174
174
|
`rshow theme publish <dir> [--label l] [--build cmd]` needs a `theme.json` with a `name`, publishes the folder as `theme-<name>`, sets it public and prints `/_themes/<name>@<n>/`.
|
|
175
175
|
`rshow theme list` prints the theme artifacts and the version each one serves.
|
|
176
176
|
`rshow show <slug>` prints the artifact, its versions, its shares, its pin and its URLs.
|
|
177
|
-
`rshow delete <slug> --yes` deletes the artifact and every version.
|
|
177
|
+
`rshow delete <slug> --yes` deletes the artifact and every version, and `--version <n>` deletes only that version.
|
|
178
178
|
It needs `--yes`, and it needs a yes from the person.
|
|
179
|
+
A theme or a theme version also needs `--force`, because pages link to it.
|
|
180
|
+
A public version can stay visible for up to 5 minutes after the delete, and a theme file for longer, so tell the person this when they delete to take something down.
|
|
179
181
|
|
|
180
182
|
A preset is a small folder whose `theme.json` carries `"extends": "default"` and only token and font overrides.
|
|
181
183
|
`rshow theme new <name> [--dir <parent>] [--from default]` writes it with both modes pre-filled with the base values of `--bg`, `--fg`, `--muted`, `--accent` and `--layer-01`, and prints the path plus `next: rshow theme check <dir>`.
|
|
@@ -238,7 +240,7 @@ Later files win, and the environment beats both.
|
|
|
238
240
|
| `art` | the art base the preview proxies `/_themes/` to, set by `rshow init` or `RSHOW_ART`; without it a theme lookup is skipped with a warning |
|
|
239
241
|
| `slug` | the artifact to publish to, overridden by `--slug` |
|
|
240
242
|
| `title` | the human title, overridden by `--title` |
|
|
241
|
-
| `theme` | the theme a page should link: `<name>`, `<name>@latest` or a fixed `<name>@<n>`. `rshow config`
|
|
243
|
+
| `theme` | the theme a page should link: `<name>`, `<name>@latest` or a fixed `<name>@<n>`. Agents link `<name>@latest` and `rshow config` keeps it that way, with `theme_resolved` beside it when the lookup works |
|
|
242
244
|
| `tokens` | token overrides recorded and printed by `rshow config`. No command writes them into a page, so apply them by hand |
|
|
243
245
|
| `build` | the command `publish` runs in the folder first |
|
|
244
246
|
| `out` | the folder under `<dir>` to publish, default `dist` |
|
|
@@ -30,11 +30,11 @@ A dashboard that nobody filters is a report with extra steps.
|
|
|
30
30
|
<meta charset="utf-8">
|
|
31
31
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
32
32
|
<title>Write-ahead log, results per run</title>
|
|
33
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
34
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
35
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
36
|
-
<script src="/_themes/default@
|
|
37
|
-
<script defer src="/_themes/default@
|
|
33
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
34
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
35
|
+
<link rel="stylesheet" href="/_themes/default@latest/dashboard.css">
|
|
36
|
+
<script src="/_themes/default@latest/mode.js"></script>
|
|
37
|
+
<script defer src="/_themes/default@latest/dashboard.js"></script>
|
|
38
38
|
</head>
|
|
39
39
|
<body>
|
|
40
40
|
<div class="dashboard" data-src="results.csv" data-facet="workload"
|
|
@@ -8,7 +8,7 @@ It reads the files a publish would upload, so for a prerendered site it reads th
|
|
|
8
8
|
|
|
9
9
|
- One `index.html` at the root of the folder you publish.
|
|
10
10
|
- Every other path inside the artifact is relative and has no leading slash, such as `chart.svg`.
|
|
11
|
-
- The
|
|
11
|
+
- The root-relative prefixes are `/_themes/<name>@latest/`, `/_themes/<name>@<n>/` and `/_data/`, and all point at the host on purpose.
|
|
12
12
|
- At most 2000 files and 100 MiB per version, and at most 25 MiB per file.
|
|
13
13
|
- No theme file in the artifact.
|
|
14
14
|
No `deck.css`, no `page.css`, no font file, no `assets/` copy of a theme.
|
|
@@ -34,6 +34,7 @@ The theme files under `/_themes/` count as `'self'`, so a linked theme needs no
|
|
|
34
34
|
## CDN builds, pinned
|
|
35
35
|
|
|
36
36
|
Pin the exact version in the URL and never write `@latest` or a moving tag, which `rshow check` counts as an error.
|
|
37
|
+
A theme link is the one moving link that is allowed, so `/_themes/<name>@latest/` is right and a number is for a frozen page.
|
|
37
38
|
|
|
38
39
|
| Library | Pinned URL |
|
|
39
40
|
|---|---|
|
|
@@ -27,8 +27,8 @@ A single file published on its own becomes `index.html` and nothing else is uplo
|
|
|
27
27
|
|
|
28
28
|
## The skeleton
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
Every link
|
|
30
|
+
Link the theme at `@latest`, so a theme fix reaches the page with no republish. Write a number only when the person asks to freeze a page, such as a talk on the day it is given. A page frozen on a number needs 8 or newer for math.
|
|
31
|
+
Every link names the same theme on purpose, and all of them use `@latest` or all use the same number, because a mix of two versions renders somewhere between two designs.
|
|
32
32
|
|
|
33
33
|
```html
|
|
34
34
|
<!doctype html>
|
|
@@ -37,10 +37,10 @@ Every link carries the same version on purpose, because a mixed version renders
|
|
|
37
37
|
<meta charset="utf-8">
|
|
38
38
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
39
39
|
<title>Q3 latency report</title>
|
|
40
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
41
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
42
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
43
|
-
<script src="/_themes/default@
|
|
40
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
41
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
42
|
+
<link rel="stylesheet" href="/_themes/default@latest/page.css">
|
|
43
|
+
<script src="/_themes/default@latest/mode.js"></script>
|
|
44
44
|
<style>:root{--accent: #0f62fe;}</style>
|
|
45
45
|
</head>
|
|
46
46
|
<body>
|
|
@@ -164,7 +164,7 @@ Put the same thing in `rshow.json` when it should not be retyped:
|
|
|
164
164
|
{
|
|
165
165
|
"slug": "status",
|
|
166
166
|
"title": "Cluster status",
|
|
167
|
-
"theme": "default@
|
|
167
|
+
"theme": "default@latest",
|
|
168
168
|
"build": "npm run build",
|
|
169
169
|
"out": "dist"
|
|
170
170
|
}
|
|
@@ -37,12 +37,12 @@ The status line beside the buttons always names the width and the height, so the
|
|
|
37
37
|
<meta charset="utf-8">
|
|
38
38
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
39
39
|
<title>Immutable artifacts for reproducible figures</title>
|
|
40
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
41
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
42
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
43
|
-
<script src="/_themes/default@
|
|
40
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
41
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
42
|
+
<link rel="stylesheet" href="/_themes/default@latest/poster.css">
|
|
43
|
+
<script src="/_themes/default@latest/mode.js"></script>
|
|
44
44
|
<script defer src="https://cdn.jsdelivr.net/npm/qrcode-generator@1.4.4/qrcode.js"></script>
|
|
45
|
-
<script defer src="/_themes/default@
|
|
45
|
+
<script defer src="/_themes/default@latest/poster.js"></script>
|
|
46
46
|
</head>
|
|
47
47
|
<body>
|
|
48
48
|
|
|
@@ -38,11 +38,11 @@ Link `fonts.css`, `tokens.css` and `project.css`, then `mode.js` in the head and
|
|
|
38
38
|
<meta charset="utf-8">
|
|
39
39
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
40
40
|
<title>Immutable artifacts for reproducible figures</title>
|
|
41
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
42
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
43
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
44
|
-
<script src="/_themes/default@
|
|
45
|
-
<script defer src="/_themes/default@
|
|
41
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
42
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
43
|
+
<link rel="stylesheet" href="/_themes/default@latest/project.css">
|
|
44
|
+
<script src="/_themes/default@latest/mode.js"></script>
|
|
45
|
+
<script defer src="/_themes/default@latest/project.js"></script>
|
|
46
46
|
</head>
|
|
47
47
|
<body>
|
|
48
48
|
<div class="project">
|
|
@@ -35,11 +35,11 @@ Link `fonts.css`, `tokens.css` and `report.css`, then `mode.js` in the head and
|
|
|
35
35
|
<meta charset="utf-8">
|
|
36
36
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
37
37
|
<title>Publishing a folder as an immutable artifact</title>
|
|
38
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
39
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
40
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
41
|
-
<script src="/_themes/default@
|
|
42
|
-
<script defer src="/_themes/default@
|
|
38
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
39
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
40
|
+
<link rel="stylesheet" href="/_themes/default@latest/report.css">
|
|
41
|
+
<script src="/_themes/default@latest/mode.js"></script>
|
|
42
|
+
<script defer src="/_themes/default@latest/report.js"></script>
|
|
43
43
|
</head>
|
|
44
44
|
<body>
|
|
45
45
|
<div class="report">
|
|
@@ -109,7 +109,11 @@ Numbering is generated, so never type a number into a heading.
|
|
|
109
109
|
|
|
110
110
|
`report.js` puts `Figure 1.` or `Table 1.` in front of the caption and counts in document order, so give every one an `id`.
|
|
111
111
|
Draw the figure as inline `<svg>` with the colours from tokens, and give it a `viewBox` so it scales.
|
|
112
|
-
An equation is `<div class="equation" id="eq-bytes">` with
|
|
112
|
+
An equation is `<div class="equation" id="eq-bytes">` with a `<div class="math">` of LaTeX inside it, and `report.js` adds `(1)` at the end of the line.
|
|
113
|
+
The report links `math.css` in the head and `math.js` before `report.js`, and `rshow check` reports bad LaTeX as an error.
|
|
114
|
+
Inline math is a `<span class="math">` inside the sentence, and a wide equation scrolls inside its own box on a phone.
|
|
115
|
+
Write `<` as `<` and `&` as `&` inside the LaTeX, and `&` where lines align in a LaTeX alignment.
|
|
116
|
+
A `$...$` in the prose is not math: it is text, so a price such as `$5` stays a price.
|
|
113
117
|
Mark example data as example data in the caption, and never present a number you did not measure.
|
|
114
118
|
|
|
115
119
|
## Cross-references
|
|
@@ -23,11 +23,11 @@ A sketch is also the honest shape for a workshop, where a tidy drawing would end
|
|
|
23
23
|
## Markup
|
|
24
24
|
|
|
25
25
|
```html
|
|
26
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
27
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
28
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
29
|
-
<script src="/_themes/default@
|
|
30
|
-
<script defer src="/_themes/default@
|
|
26
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
27
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
28
|
+
<link rel="stylesheet" href="/_themes/default@latest/sketch.css">
|
|
29
|
+
<script src="/_themes/default@latest/mode.js"></script>
|
|
30
|
+
<script defer src="/_themes/default@latest/sketch.js"></script>
|
|
31
31
|
...
|
|
32
32
|
<div class="sketch" data-src="drawing.excalidraw" data-store="sketch-main"></div>
|
|
33
33
|
```
|
|
@@ -26,11 +26,11 @@ The viewer and the TUI kit are the theme's, and both are guided kits: the frame
|
|
|
26
26
|
## The viewer
|
|
27
27
|
|
|
28
28
|
```html
|
|
29
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
30
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
31
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
32
|
-
<script src="/_themes/default@
|
|
33
|
-
<script defer src="/_themes/default@
|
|
29
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
30
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
31
|
+
<link rel="stylesheet" href="/_themes/default@latest/terminal.css">
|
|
32
|
+
<script src="/_themes/default@latest/mode.js"></script>
|
|
33
|
+
<script defer src="/_themes/default@latest/terminal.js"></script>
|
|
34
34
|
...
|
|
35
35
|
<figure class="terminal" data-mode="ansi" data-src="capture.ans"
|
|
36
36
|
data-cols="100" data-rows="30" data-title="procview" data-palette="default"></figure>
|
|
@@ -32,7 +32,7 @@ A topic on its own is not a slide.
|
|
|
32
32
|
|
|
33
33
|
## 2. Skeleton
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
Link the theme at `@latest`, so a theme fix reaches the deck with no republish. Write a number only when the person asks to freeze a deck, such as a talk on the day it is given. A deck frozen on a number needs 8 or newer for math.
|
|
36
36
|
|
|
37
37
|
```html
|
|
38
38
|
<!doctype html>
|
|
@@ -41,9 +41,12 @@ Replace `<name>@<n>` with the `theme` value that `rshow config <dir>` prints, wh
|
|
|
41
41
|
<meta charset="utf-8">
|
|
42
42
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
43
43
|
<title>Talk title</title>
|
|
44
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
45
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
46
|
-
<link rel="stylesheet" href="/_themes/default@
|
|
44
|
+
<link rel="stylesheet" href="/_themes/default@latest/fonts.css">
|
|
45
|
+
<link rel="stylesheet" href="/_themes/default@latest/tokens.css">
|
|
46
|
+
<link rel="stylesheet" href="/_themes/default@latest/deck.css">
|
|
47
|
+
<!-- a deck that writes math links these two, and math.js goes before deck.js -->
|
|
48
|
+
<link rel="stylesheet" href="/_themes/default@latest/math.css">
|
|
49
|
+
<script defer src="/_themes/default@latest/math.js"></script>
|
|
47
50
|
</head>
|
|
48
51
|
<body>
|
|
49
52
|
<main class="deck">
|
|
@@ -65,12 +68,12 @@ Replace `<name>@<n>` with the `theme` value that `rshow config <dir>` prints, wh
|
|
|
65
68
|
</section>
|
|
66
69
|
|
|
67
70
|
</main>
|
|
68
|
-
<script src="/_themes/default@
|
|
71
|
+
<script src="/_themes/default@latest/deck.js"></script>
|
|
69
72
|
</body>
|
|
70
73
|
</html>
|
|
71
74
|
```
|
|
72
75
|
|
|
73
|
-
The three stylesheet links and the script carry
|
|
76
|
+
The three stylesheet links and the script carry `@latest` on purpose, so a theme fix reaches every deck on the next open.
|
|
74
77
|
The deck needs no `mode.js`, because `deck.js` reads the same key and `t` does the same work.
|
|
75
78
|
Override a token in one `:root` block after the theme links when the deck needs its own accent, with no limit on the declarations.
|
|
76
79
|
An inline `<style>` block after the theme links may also carry a layout of the deck's own, as section 3 says.
|
|
@@ -85,6 +88,7 @@ Every slide is a `<section class="slide ...">`, and the second class is one of t
|
|
|
85
88
|
One series is drawn in the accent blue and two or more take `--chart-1`, `--chart-2` and so on in order.
|
|
86
89
|
- `table` for a clean data table and `code` for one command.
|
|
87
90
|
- `two-col` for two blocks of text, `quote` for one sentence and `big-number` for one number.
|
|
91
|
+
- A slide with an equation is a `bullets` slide with one `<div class="math">` of LaTeX under the title, and the deck links `math.css` and `math.js` for it.
|
|
88
92
|
|
|
89
93
|
A sparse slide is centred a little above the middle of the canvas, so the air sits under the block.
|
|
90
94
|
A bullets slide puts its points under the title at 28px with a 1.4 line, five at most.
|
|
@@ -102,6 +106,7 @@ Vary the rhythm: do not run more than three text slides (`two-col` or `bullets`)
|
|
|
102
106
|
- Every slide gets one `<aside class="notes">`, including the title slide, because a slide without one shows nothing in the notes window.
|
|
103
107
|
- Keep a note under 60 words.
|
|
104
108
|
It is what you say, not what the room reads.
|
|
109
|
+
- A note holds no math: an equation inside an `aside.notes` stays as its LaTeX, because the notes window loads no math stylesheet.
|
|
105
110
|
- Press `n` for the notes window, which also names the next slide.
|
|
106
111
|
- Press `p` for the presenter view: the current slide, the next slide, the notes and an elapsed timer, kept in step with the deck.
|
|
107
112
|
- Put `class="step"` on any element inside a slide to reveal it one press later, because `deck.js` selects every `.step` in the slide.
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
- two-col
|
|
15
15
|
- quote
|
|
16
16
|
- big-number
|
|
17
|
+
- math (an equation on a bullets slide)
|
|
17
18
|
- your own layout
|
|
18
19
|
|
|
19
20
|
One markup example per layout, all inside `<main class="deck">`.
|
|
@@ -252,6 +253,20 @@ The unit belongs in the statement and the source goes under it.
|
|
|
252
253
|
|
|
253
254
|
A number you cannot measure is `[PLACEHOLDER]` until it is real, and a number that stands for an example says so in the source line.
|
|
254
255
|
|
|
256
|
+
## math
|
|
257
|
+
|
|
258
|
+
An equation takes a `bullets` slide: a takeaway title and one `div.math`.
|
|
259
|
+
The LaTeX is the text of the element, and the deck links `math.css` and `math.js` for it.
|
|
260
|
+
A note holds words, not math.
|
|
261
|
+
|
|
262
|
+
```html
|
|
263
|
+
<section class="slide bullets">
|
|
264
|
+
<h2>A republish sends only the bytes that changed</h2>
|
|
265
|
+
<div class="math">\mathrm{sent}(n) = \sum_{f \in \mathrm{new}(n)} |f|</div>
|
|
266
|
+
<aside class="notes"><p>The sum drops every file the host already holds.</p></aside>
|
|
267
|
+
</section>
|
|
268
|
+
```
|
|
269
|
+
|
|
255
270
|
## your own layout
|
|
256
271
|
|
|
257
272
|
A layout of your own takes a short class name and sits second on the slide, in the same slot as the twelve.
|
package/themes/default/deck.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Markup: <main class="deck"><section class="slide">...</section>...</main>
|
|
5
5
|
* Keys: arrows, space, PageUp/PageDown, Home/End, f = fullscreen, n = notes,
|
|
6
6
|
* p = presenter view, t = mode (system, light, dark).
|
|
7
|
-
* Mouse: click advances, shift-click goes back,
|
|
7
|
+
* Mouse: a click on empty space advances, shift-click goes back, a click or a
|
|
8
|
+
* drag on text selects it, swipe left/right navigates.
|
|
8
9
|
* URL hash #N keeps the slide. Steps reveal one per advance.
|
|
9
10
|
*
|
|
10
11
|
* Mode. The deck and a page share one storage key, "rshow-mode", holding
|
|
@@ -177,7 +178,7 @@
|
|
|
177
178
|
deck.style.transform = 'translate(' + x + 'px, ' + y + 'px) scale(' + scale + ')';
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
function
|
|
181
|
+
function writeHashNow() {
|
|
181
182
|
var want = '#' + (current + 1);
|
|
182
183
|
if (window.location.hash === want) {
|
|
183
184
|
return;
|
|
@@ -185,10 +186,27 @@
|
|
|
185
186
|
try {
|
|
186
187
|
window.history.replaceState(null, '', want);
|
|
187
188
|
} catch (err) {
|
|
188
|
-
|
|
189
|
+
// Assigning the hash here fires hashchange, and that listener would send
|
|
190
|
+
// the deck back to an old slide, so the address is left as it is.
|
|
189
191
|
}
|
|
190
192
|
}
|
|
191
193
|
|
|
194
|
+
// A browser counts the replaceState calls it honours and drops the rest: in
|
|
195
|
+
// Chrome a burst of keys leaves the address on an old slide, and in Safari the
|
|
196
|
+
// call throws. One write, 300 ms after the deck comes to rest, keeps the
|
|
197
|
+
// address current without touching that limit.
|
|
198
|
+
var hashTimer = null;
|
|
199
|
+
|
|
200
|
+
function writeHash() {
|
|
201
|
+
if (hashTimer) {
|
|
202
|
+
window.clearTimeout(hashTimer);
|
|
203
|
+
}
|
|
204
|
+
hashTimer = window.setTimeout(function () {
|
|
205
|
+
hashTimer = null;
|
|
206
|
+
writeHashNow();
|
|
207
|
+
}, 300);
|
|
208
|
+
}
|
|
209
|
+
|
|
192
210
|
function slideTitle(n) {
|
|
193
211
|
var h = slides[n].querySelector('h1, h2, h3');
|
|
194
212
|
var text = h ? h.textContent : '';
|
|
@@ -635,14 +653,78 @@
|
|
|
635
653
|
}
|
|
636
654
|
});
|
|
637
655
|
|
|
656
|
+
// Text under a point, so a click on it can select instead of navigating. The
|
|
657
|
+
// deck canvas is scaled by a transform, but client rects are already in screen
|
|
658
|
+
// space, so the point needs no maths.
|
|
659
|
+
function onText(x, y) {
|
|
660
|
+
try {
|
|
661
|
+
var node = null;
|
|
662
|
+
if (document.caretRangeFromPoint) {
|
|
663
|
+
var caret = document.caretRangeFromPoint(x, y);
|
|
664
|
+
node = caret ? caret.startContainer : null;
|
|
665
|
+
} else if (document.caretPositionFromPoint) {
|
|
666
|
+
var position = document.caretPositionFromPoint(x, y);
|
|
667
|
+
node = position ? position.offsetNode : null;
|
|
668
|
+
}
|
|
669
|
+
if (!node || node.nodeType !== 3) {
|
|
670
|
+
return false;
|
|
671
|
+
}
|
|
672
|
+
var range = document.createRange();
|
|
673
|
+
range.selectNodeContents(node);
|
|
674
|
+
var rects = range.getClientRects();
|
|
675
|
+
for (var k = 0; k < rects.length; k += 1) {
|
|
676
|
+
if (x >= rects[k].left && x <= rects[k].right &&
|
|
677
|
+
y >= rects[k].top && y <= rects[k].bottom) {
|
|
678
|
+
return true;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return false;
|
|
682
|
+
} catch (err) {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
var pressX = 0;
|
|
688
|
+
var pressY = 0;
|
|
689
|
+
var pressTracked = false;
|
|
690
|
+
|
|
691
|
+
deck.addEventListener('mousedown', function (event) {
|
|
692
|
+
if (event.button !== 0) {
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
pressTracked = true;
|
|
696
|
+
pressX = event.clientX;
|
|
697
|
+
pressY = event.clientY;
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
// A drag that selects text ends in a click too, so a click counts as a key
|
|
701
|
+
// press only when the pointer stayed put, it was a single click, the selection
|
|
702
|
+
// is empty and there is no text under it.
|
|
638
703
|
deck.addEventListener('click', function (event) {
|
|
704
|
+
var moved = pressTracked &&
|
|
705
|
+
(Math.abs(event.clientX - pressX) > 4 || Math.abs(event.clientY - pressY) > 4);
|
|
706
|
+
pressTracked = false;
|
|
639
707
|
var node = event.target;
|
|
708
|
+
var tag;
|
|
640
709
|
while (node && node !== deck) {
|
|
641
|
-
|
|
710
|
+
tag = node.tagName;
|
|
711
|
+
if (tag === 'A' || tag === 'BUTTON' || tag === 'INPUT' || tag === 'SELECT' ||
|
|
712
|
+
tag === 'TEXTAREA' || tag === 'LABEL' || tag === 'SUMMARY' ||
|
|
713
|
+
node.isContentEditable) {
|
|
642
714
|
return;
|
|
643
715
|
}
|
|
644
716
|
node = node.parentNode;
|
|
645
717
|
}
|
|
718
|
+
if (event.detail > 1 || moved) {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
var sel = window.getSelection ? window.getSelection() : null;
|
|
722
|
+
if (sel && !sel.isCollapsed && String(sel) !== '') {
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
if (onText(event.clientX, event.clientY)) {
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
646
728
|
if (event.shiftKey) {
|
|
647
729
|
prev();
|
|
648
730
|
} else {
|
|
@@ -11,14 +11,20 @@
|
|
|
11
11
|
<link rel="stylesheet" href="/_themes/<name>@<n>/fonts.css">
|
|
12
12
|
<link rel="stylesheet" href="/_themes/<name>@<n>/tokens.css">
|
|
13
13
|
<link rel="stylesheet" href="/_themes/<name>@<n>/deck.css">
|
|
14
|
+
<link rel="stylesheet" href="/_themes/<name>@<n>/math.css">
|
|
15
|
+
<script defer src="/_themes/<name>@<n>/math.js"></script>
|
|
14
16
|
<script src="/_themes/<name>@<n>/deck.js"></script>
|
|
15
17
|
|
|
16
18
|
This copy links the theme folder itself, so it previews from a local checkout
|
|
17
|
-
with `rshow preview .` from this folder, and no network.
|
|
19
|
+
with `rshow preview .` from this folder, and no network. math.css and math.js
|
|
20
|
+
are the math addon of the theme and are optional: a deck with an equation
|
|
21
|
+
links them, and math.js goes before deck.js. A $ in the prose of a slide is a
|
|
22
|
+
price, not a formula.
|
|
18
23
|
|
|
19
24
|
Twelve slides, one per layout in deck.css, so every class the theme ships is
|
|
20
25
|
shown here: title, statement, bullets, section, figure, chart, table,
|
|
21
|
-
two-col, code, figure-two, quote, big-number.
|
|
26
|
+
two-col, code, figure-two, quote, big-number. A thirteenth slide carries one
|
|
27
|
+
equation and shows the math addon.
|
|
22
28
|
|
|
23
29
|
The numbers on the chart and the table are example data. They are round on
|
|
24
30
|
purpose and the caption says so, because an example must never read as a
|
|
@@ -31,6 +37,8 @@
|
|
|
31
37
|
<link rel="stylesheet" href="../fonts.css">
|
|
32
38
|
<link rel="stylesheet" href="../tokens.css">
|
|
33
39
|
<link rel="stylesheet" href="../deck.css">
|
|
40
|
+
<link rel="stylesheet" href="../math.css">
|
|
41
|
+
<script defer src="../math.js"></script>
|
|
34
42
|
</head>
|
|
35
43
|
<body>
|
|
36
44
|
|
|
@@ -294,6 +302,15 @@
|
|
|
294
302
|
</aside>
|
|
295
303
|
</section>
|
|
296
304
|
|
|
305
|
+
<section class="slide bullets">
|
|
306
|
+
<h2>A republish sends only the bytes that changed</h2>
|
|
307
|
+
<div class="math">\mathrm{sent}(n) = \sum_{f \in \mathrm{new}(n)} |f|</div>
|
|
308
|
+
<aside class="notes">
|
|
309
|
+
<p>Same folder, second publish: the sum drops every file the host already
|
|
310
|
+
holds, so what leaves the laptop is the edit and nothing else.</p>
|
|
311
|
+
</aside>
|
|
312
|
+
</section>
|
|
313
|
+
|
|
297
314
|
<section class="slide big-number">
|
|
298
315
|
<p class="value">5 versions, 1 link</p>
|
|
299
316
|
<p class="caption">Five publishes of one folder, each at its own path, all reachable from the link the first publish printed.</p>
|
|
@@ -12,25 +12,32 @@
|
|
|
12
12
|
<link rel="stylesheet" href="/_themes/<name>@<n>/fonts.css">
|
|
13
13
|
<link rel="stylesheet" href="/_themes/<name>@<n>/tokens.css">
|
|
14
14
|
<link rel="stylesheet" href="/_themes/<name>@<n>/report.css">
|
|
15
|
+
<link rel="stylesheet" href="/_themes/<name>@<n>/math.css">
|
|
15
16
|
<script src="/_themes/<name>@<n>/mode.js"></script>
|
|
17
|
+
<script defer src="/_themes/<name>@<n>/math.js"></script>
|
|
16
18
|
<script defer src="/_themes/<name>@<n>/report.js"></script>
|
|
17
19
|
|
|
18
20
|
This copy links the theme folder itself, so it previews from a local checkout
|
|
19
21
|
and makes no remote request. mode.js runs in the head, before the body paints,
|
|
20
|
-
so a reader who chose dark never sees a white flash.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
so a reader who chose dark never sees a white flash. math.css and math.js are
|
|
23
|
+
the math addon of the theme and are optional: a report that writes LaTeX links
|
|
24
|
+
them, and the equation below is the one line that does. math.js is deferred and
|
|
25
|
+
goes before report.js. report.js is deferred: it numbers the sections, figures
|
|
26
|
+
and tables, resolves the cross-references, builds the contents and moves the
|
|
27
|
+
notes into the margin. With JavaScript off the document is still a readable
|
|
28
|
+
paper, it just loses the generated labels and the equation shows its LaTeX.
|
|
24
29
|
|
|
25
|
-
Six sections, two figures, one table, three notes
|
|
26
|
-
authors, the affiliations, the date and the version line are
|
|
27
|
-
fill them in when the report is real. Every number in figure 2
|
|
28
|
-
prose around it is example data and says so.
|
|
30
|
+
Six sections, two figures, one table, one equation, three notes and six
|
|
31
|
+
references. The authors, the affiliations, the date and the version line are
|
|
32
|
+
placeholders: fill them in when the report is real. Every number in figure 2
|
|
33
|
+
and in the prose around it is example data and says so.
|
|
29
34
|
-->
|
|
30
35
|
<link rel="stylesheet" href="../fonts.css">
|
|
31
36
|
<link rel="stylesheet" href="../tokens.css">
|
|
32
37
|
<link rel="stylesheet" href="../report.css">
|
|
38
|
+
<link rel="stylesheet" href="../math.css">
|
|
33
39
|
<script src="../mode.js"></script>
|
|
40
|
+
<script defer src="../math.js"></script>
|
|
34
41
|
<script defer src="../report.js"></script>
|
|
35
42
|
</head>
|
|
36
43
|
<body>
|
|
@@ -193,10 +200,10 @@
|
|
|
193
200
|
<p>The cost of a publish follows the same rule. Let the files of a version
|
|
194
201
|
be <code>files(n)</code> and let the host's store be the set of hashes it
|
|
195
202
|
already holds. The bytes a publish must send are the size of every file
|
|
196
|
-
whose hash is missing from the store.</p>
|
|
203
|
+
<span class="math">f</span> whose hash is missing from the store.</p>
|
|
197
204
|
|
|
198
205
|
<div class="equation" id="eq-bytes">
|
|
199
|
-
<
|
|
206
|
+
<div class="math">\mathrm{bytes}(n) = \sum_{f \in \mathrm{new}(n)} |f|</div>
|
|
200
207
|
</div>
|
|
201
208
|
|
|
202
209
|
<p>The equation is the whole reason a republish of a mostly unchanged deck
|
|
Binary file
|
|
Binary file
|
|
Binary file
|