cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

Docs: notebook cells and ux as pictures; doclint refuses drawn screens

Dami committed afd55ed
The notebook page shows its cells and nu's check as stills, with what
each mark and word means in one table that ux.md's color-blind list
links to. The visual rules open with a still of the palette. doclint
fails a code block that draws 012's screen (box drawing with the menu
bar or toolbar, or the grid's column headers) and points at the
pictures convention.
commit
afd55ed8d2f4a20bd35415d532841f322a98a174
parent
405058c18bfee2db72794869f921a6babe779b2b
author
Dami <dami.etoile@gmail.com>
kind
docs risk score 1.5 of 3, Jev's estimate
14 files changed, +158 -35
Mdocs/contributing/ux.md10++++-
Adocs/media/notebook-cells-dark.pngbin
Adocs/media/notebook-cells-light.pngbin
Adocs/media/notebook-nu-error-dark.pngbin
Adocs/media/notebook-nu-error-light.pngbin
Adocs/media/palette-dark.pngbin
Adocs/media/palette-light.pngbin
Mdocs/nushell/notebooks.md63+++++++++++++++---------------
Me2e/stills_test.go2+
Ae2e/testdata/screens/docs-notebook-cells-light.html26++++++++++++
Ae2e/testdata/screens/docs-notebook-cells.html26++++++++++++
Ae2e/testdata/screens/docs-notebook-nu-error-light.html16++++++++
Ae2e/testdata/screens/docs-notebook-nu-error.html16++++++++
Mscripts/doclint/main.go34+++++++++++++++-
M docs/contributing/ux.md +9 -1
@@ -52,6 +52,14 @@ follow-up task.
5252 5353 ## Visual rules5454 55+The palette over a sheet shows most of them at once: bars that fill56+the width, an overlay framed in light lines with its title in the top57+border and a count in the bottom one, keys drawn as chips, and the58+status line saying what the highlighted item does.59+60+![The command palette open over a budget: the mode indicator saying MENU, a framed list of commands with their keys as chips and a count in the bottom border, and the status line describing the highlighted one](../media/palette-dark.png#gh-dark-mode-only)61+![The command palette open over a budget: the mode indicator saying MENU, a framed list of commands with their keys as chips and a count in the bottom border, and the status line describing the highlighted one](../media/palette-light.png#gh-light-mode-only)62+5563 - Style only through `theme` roles (`internal/ui/theme`). No inline5664 `lipgloss.NewStyle()` in views. Need a new role? Add it to `theme` with a5765 comment saying what it's for, in both the dark and light variants.
@@ -99,7 +107,7 @@ there.
99107 | Entries failing validation | A dotted underline, and `Invalid:` with the rule on the context line |100108 | Values an array spilled | Italic, and `Spilled from B2` on the context line |101109 | Linked files' rows, following, paused or failing | Italic; `●`, `‖` or `!` beside the tab's name and on the context line, with the state in words (`Following`, `Paused`, the error) |102-| A notebook's cells and outputs | `❯` before the tab's name; `▌` left of the active cell and `▎` left of the others selected; a heavy box around the cell being edited; the prompt's and the box's words for its state (`[*]:` and `running`, `waiting`, `failed`, `stale`); `■` for `▶` while it runs; `output hidden` for a hidden output, and which rows show for one scrolled; `×` before an error; an output table's header bold and underlined; an output sent to a sheet in italic, with `Output of files` on the context line; a problem nu finds in the cell being written curly-underlined, in words on the context line with the caret on it |110+| A notebook's cells and outputs | Marks and words, listed in [Notebooks](../nushell/notebooks.md#reading-a-cell): the bar left of the active cell, a heavy box while it's edited, the prompt's and the box's words for its state, `×` before an error, an output sent to a sheet in italic |103111 | A table's header row | Bold and underlined, when the table styles its header; `Table Sales, column Amount` on the context line |104112 | Pivot table results | Their headings (`SUM of Units`, `Grand Total`), and a note in words when an edit is refused |105113 | Protected ranges | A question in words before an edit (`A1:B2 is protected.`) |
A docs/media/notebook-cells-dark.png +0 -0

Binary file.

A docs/media/notebook-cells-light.png +0 -0

Binary file.

A docs/media/notebook-nu-error-dark.png +0 -0

Binary file.

A docs/media/notebook-nu-error-light.png +0 -0

Binary file.

A docs/media/palette-dark.png +0 -0

Binary file.

A docs/media/palette-light.png +0 -0

Binary file.

M docs/nushell/notebooks.md +32 -31
@@ -38,27 +38,28 @@ works as before.
3838 3939 The tab looks and works like Jupyter's: a toolbar over the cells, a4040 code cell's pipeline in a box with its prompt at the left and a `▶` that41-runs it at the right, its output under it, and note cells drawn as text:41+runs it at the right, its output under it, and note cells drawn as text.4242 43-```44- ▶ Run ■ Stop ↻ Restart ▶▶ Run all │ + Add ✂ Cut ⧉ Copy ⎘ Paste │ Code ▾ nu ○ idle45- big: reads $files; read as $big, nu.big in formulas ──────────────── Enter edit46- Files47- What's big in the repo, from ls.48-49-▌ ╭─ big ───────────────────────────────────────────── ✓ <1s ─╮50-▌ [2]: │ big = $files | where size > 1kb │ ▶51-▌ │ | sort-by size --reverse │52-▌ ╰────────────────────────────────────────────────────────────╯53-▌ Out[2]: name size54-▌ README.md 9.8 kB55-▌ 012 4.2 kB56-```43+![A notebook of a note and two code cells: files lists the directory, and the second cell, selected, keeps its files over 1 kB; each output is a table under its cell, and the toolbar runs, adds and moves cells](../media/notebook-cells-dark.png#gh-dark-mode-only)44+![A notebook of a note and two code cells: files lists the directory, and the second cell, selected, keeps its files over 1 kB; each output is a table under its cell, and the toolbar runs, adds and moves cells](../media/notebook-cells-light.png#gh-light-mode-only)45+46+### Reading a cell47+48+Every state shows in words or marks as well as in color, so a notebook49+reads the same on a terminal without it:50+51+| Where | Shows |52+|---|---|53+| The tab | `❯` before the notebook's name |54+| Left of the cells | A bar at the active cell, blue in command mode and green in edit mode, and a thinner one at the others selected ([Keys](#keys)) |55+| The box | Light lines, and heavy ones around the cell being edited |56+| The prompt | How many runs came before this one: `[2]:`, `[*]:` while it runs, `[ ]:` before it has; `Out[2]:` marks the output of that run |57+| The box's top border | The cell's name at the left, and at the right how its run stands (below): `waiting`, `running`, ✓ and how long it took, `failed`, `stale`, or `saved` for an output read from the file |58+| Right of the box | `▶` runs the cell, `■` stops it while it runs |59+| The output | What it is ([below](#outputs)): a table under its header, bold and underlined; `×` before an error; `output hidden`; which rows show in its window |60+| The context line | What the cell reads and how others read it (`big: reads $files; read as $big, nu.big in formulas`), the keys that apply, and what nu says about the cell being written, underlined curly in the cell ([Writing a cell](#writing-a-cell)) |5761 58-The prompt says how many runs came before this one (`[2]:`, `[*]:` while59-it runs, `[ ]:` before it has), and `Out[2]:` marks the output of that60-run. The box's top border names the cell and says at its right how its61-run stands, `saved` for an output read from the file:62+A cell's run goes through these states:6263 6364 ```mermaid6465 stateDiagram-v2
@@ -82,6 +83,8 @@ stateDiagram-v2
8283 A source is shown whole: a line too long for the screen wraps before a8384 pipe where it can, its next rows indented.8485 86+### Outputs87+8588 Outputs are drawn by what they are, with values formatted as cells8689 ([Types](types.md)):8790
@@ -122,6 +125,8 @@ descending order (again for the output's own order), `/` keeps the rows
122125 holding what's typed, and Esc (or `◀ Back`) goes back. The output itself123126 doesn't change.124127 128+### Note cells129+125130 Note cells are Markdown: headings, **bold**, *italic*, `code`, links (the126131 terminal opens them), lists and quotes. They're drawn as text, without a127132 box or a prompt, and show their Markdown in a box only while edited.
@@ -142,11 +147,10 @@ stateDiagram-v2
142147 Output --> Command: Esc143148 ```144149 145-A bar at the left marks the active cell: `▌`, blue in command mode and146-green in edit mode, where the cell's box is drawn in heavy lines too, so147-the mode reads without color. Shift+Up and Shift+Down (or `K` and `J`,148-or Shift+click) select the cells passed over as well, marked `▎`, and149-the commands below that act on "the cells" act on all of them: run,150+The bar left of the active cell and the box's lines say which mode151+you're in ([Reading a cell](#reading-a-cell)). Shift+Up and Shift+Down152+(or `K` and `J`, or Shift+click) select the cells passed over as well,153+and the commands below that act on "the cells" act on all of them: run,150154 delete, copy, cut, move, make notes or code, hide or clear outputs.151155 152156 | Key | In command mode |
@@ -226,12 +230,8 @@ keywords, operators; flags stay plain), and `nu --ide-check` what's
226230 wrong. A problem is underlined with a curly line, and with the caret on227231 it the context line says what nu said:228232 229-```230- [ ] not run231-│ $files | sort-by size --revrse232- ~~~~~~~~233-The `sort-by` command doesn't have flag `revrse`.234-```233+![A cell being edited, its box in heavy lines: the misspelled flag --revrse is underlined with a curly line, and the context line says the sort-by command doesn't have that flag](../media/notebook-nu-error-dark.png#gh-dark-mode-only)234+![A cell being edited, its box in heavy lines: the misspelled flag --revrse is underlined with a curly line, and the context line says the sort-by command doesn't have that flag](../media/notebook-nu-error-light.png#gh-light-mode-only)235235 236236 Tab asks `nu --ide-complete` too, after the notebook's own names, so it237237 completes flags, subcommands and paths as well as cells and commands.
@@ -342,7 +342,8 @@ nu.files, 3, FALSE)`), and charts and pivot tables use. It's also a
342342 [table](../sheets/tables.md#notebook-outputs-and-linked-files) by the343343 cell's name, read by column: `=SUM(big[size])`, `=COUNTIF(app[status],344344 500)`, with `big` alone its rows under the header. A cell without a345-name is given one first.345+name is given one first. On the region's cells the context line says346+whose output they are (`Output of big`).346347 347348 ```mermaid348349 sequenceDiagram
M e2e/stills_test.go +2 -0
A e2e/testdata/screens/docs-notebook-cells-light.html +26 -0
@@ -0,0 +1,26 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3+ <span style="color:var(--vt-palette-0)">cell</span> <span style="color:var(--vt-palette-0)">3:</span> <span style="color:var(--vt-palette-0)">reads</span> <span style="color:var(--vt-palette-0)">$files</span> <span style="color:var(--vt-palette-8)">─────────────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">edit</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Shift+↑↓</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">select</span>4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-4)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11+ 012 file 4.2 kB12+ CLAUDE.md file 1.0 kB13+ README.md file 9.8 kB14+ demos dir 3.1 kB15+ go.mod file 812 B16+17+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>18+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>19+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────╯</span>20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21+<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────╮</span>26+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+/</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">shortcuts</span></pre>\ No newline at end of file
A e2e/testdata/screens/docs-notebook-cells.html +26 -0
@@ -0,0 +1,26 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3+ <span style="color:var(--vt-palette-8)">cell</span> <span style="color:var(--vt-palette-8)">3:</span> <span style="color:var(--vt-palette-8)">reads</span> <span style="color:var(--vt-palette-8)">$files</span> <span style="color:var(--vt-palette-8)">─────────────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">edit</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Shift+↑↓</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">select</span>4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-6)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11+ 012 file 4.2 kB12+ CLAUDE.md file 1.0 kB13+ README.md file 9.8 kB14+ demos dir 3.1 kB15+ go.mod file 812 B16+17+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>18+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>19+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────╯</span>20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21+<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────╮</span>26+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+/</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">shortcuts</span></pre>\ No newline at end of file
A e2e/testdata/screens/docs-notebook-nu-error-light.html +16 -0
@@ -0,0 +1,16 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">EDIT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3+ <span style="color:var(--vt-palette-3)">The</span> <span style="color:var(--vt-palette-3)">`sort-by`</span> <span style="color:var(--vt-palette-3)">command</span> <span style="color:var(--vt-palette-3)">doesn&#39;t</span> <span style="color:var(--vt-palette-3)">have</span> <span style="color:var(--vt-palette-3)">flag</span> <span style="color:var(--vt-palette-3)">`revrse`.</span> <span style="color:var(--vt-palette-8)">─</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">done</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Tab</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">complete</span>4+5+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>6+ <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>7+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>8+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>9+ 012 file 4.2 kB10+ README.md file 9.8 kB11+ demos dir 3.1 kB12+13+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>14+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>15+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛</span>16+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+/</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">shortcuts</span></pre>\ No newline at end of file
A e2e/testdata/screens/docs-notebook-nu-error.html +16 -0
@@ -0,0 +1,16 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">EDIT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3+ <span style="color:var(--vt-palette-3)">The</span> <span style="color:var(--vt-palette-3)">`sort-by`</span> <span style="color:var(--vt-palette-3)">command</span> <span style="color:var(--vt-palette-3)">doesn&#39;t</span> <span style="color:var(--vt-palette-3)">have</span> <span style="color:var(--vt-palette-3)">flag</span> <span style="color:var(--vt-palette-3)">`revrse`.</span> <span style="color:var(--vt-palette-8)">─</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">done</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Tab</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">complete</span>4+5+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>6+ <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>7+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>8+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>9+ 012 file 4.2 kB10+ README.md file 9.8 kB11+ demos dir 3.1 kB12+13+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>14+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>15+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛</span>16+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+/</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">shortcuts</span></pre>\ No newline at end of file
M scripts/doclint/main.go +31 -3
@@ -10,6 +10,9 @@
1010 // "doclint:allow" and a reason, in a comment on that line (or an HTML1111 // comment in Markdown).1212 //13+// It also refuses a code block that draws 012's screen as text: a14+// picture of 012 is a still drawn from a golden screen.15+//1316 // Usage: go run ./scripts/doclint [dirs or files...]1417 package main1518
@@ -90,7 +93,7 @@ func main() {
9093 fmt.Printf("%s:%d: %s: %s\n", f.file, f.line, f.why, strings.TrimSpace(f.text))9194 }9295 if len(found) > 0 {93- fmt.Printf("doclint: %d lines describe development rather than the code\n", len(found))96+ fmt.Printf("doclint: %d findings\n", len(found))9497 os.Exit(1)9598 }9699 }
@@ -140,16 +143,21 @@ func markdown(path string) []finding {
140143 }141144 defer f.Close()142145 var out []finding143- fenced := false146+ fenced, start := false, 0147+ var block []string144148 sc := bufio.NewScanner(f)145149 sc.Buffer(make([]byte, 1<<20), 1<<20)146150 for n := 1; sc.Scan(); n++ {147151 l := sc.Text()148152 if strings.HasPrefix(strings.TrimSpace(l), "```") {149- fenced = !fenced153+ if fenced && drawnScreen(block) {154+ out = append(out, finding{path, start, "```", screenWhy})155+ }156+ fenced, start, block = !fenced, n, nil150157 continue151158 }152159 if fenced {160+ block = append(block, l)153161 continue154162 }155163 out = append(out, check(path, n, stripCode(l))...)
@@ -157,6 +165,26 @@ func markdown(path string) []finding {
157165 return out158166 }159167 168+// screenWhy is what a code block drawing 012's screen is told.169+const screenWhy = "a code block drawing 012's screen; show a still of it instead (docs/contributing/site.md#pictures-of-012)"170+171+var (172+ boxDrawing = regexp.MustCompile(`[\x{2500}-\x{257F}]`)173+ // chrome is the menu bar or the notebook's toolbar.174+ chrome = regexp.MustCompile(`File\s+Edit\s+View|▶ Run|■ Stop`)175+ // columnHeaders are the grid's column letters over its cells.176+ columnHeaders = regexp.MustCompile(`(?m)^\s*A\s{2,}B\s{2,}C(\s|$)`)177+)178+179+// drawnScreen reports whether a code block's lines draw 012's screen as180+// text: box drawing with the menu bar or the toolbar, or the grid's181+// column headers. Command output (tables a shell prints, logs) is none182+// of these.183+func drawnScreen(lines []string) bool {184+ text := strings.Join(lines, "\n")185+ return boxDrawing.MatchString(text) && chrome.MatchString(text) || columnHeaders.MatchString(text)186+}187+160188 var inlineCode = regexp.MustCompile("`[^`]*`")161189 162190 // stripCode drops inline code spans, which quote code rather than narrate.