From 41abad0159c162a34444e1df5d3e41d33098309a Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 10 Nov 2026 11:21:32 +0000 Subject: [PATCH] docs: The Book of Fabric -- the FABRIC design record as one book, built and published with every release (#138) [skip ci] `make fabric` -> build/docs/BookOfFabric.pdf (722 pages): Part I the living record (FABRIC-3), Part II the closed documents in the order written, Part III the forward-looking notes; its title page carries the version (git describe --tags: a release's tag) and the commit. Built from the same pandoc fragments as the book; the book's preamble moved into docs/book/preamble.tex, shared by both (the book builds as before, 821 pages). scripts/nightly.sh: the docs stage builds it ($DOCS/fabric.pdf); publish sends it as classifier `fabric`; gitea-release attaches every PDF in $DOCS, so every release carries it. Progress for the rest of alpha.4's documents: docs/v4.0.0/plans/2026-11-10-alpha4-documents.md. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2 --- Makefile | 6 +- docs/book/Makefile | 35 ++++++- docs/book/fabric.tex | 69 +++++++++++++ docs/book/main.tex | 94 +----------------- docs/book/preamble.tex | 97 +++++++++++++++++++ .../plans/2026-11-10-alpha4-documents.md | 26 +++++ scripts/nightly.sh | 9 +- 7 files changed, 234 insertions(+), 102 deletions(-) create mode 100644 docs/book/fabric.tex create mode 100644 docs/book/preamble.tex create mode 100644 docs/v4.0.0/plans/2026-11-10-alpha4-documents.md diff --git a/Makefile b/Makefile index c4754628..b1a7db49 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ BOARD_DIR := $(if $(TARGET),$(BOARD_DIR_$(TARGET))) SUBMAKE := $(MAKE) --no-print-directory .DEFAULT_GOAL := all -.PHONY: all boot_image boot_images write_stick docs clean clean-docs kernel boards help help-hosted sbom sbom-board \ +.PHONY: all boot_image boot_images write_stick docs fabric clean clean-docs kernel boards help help-hosted sbom sbom-board \ qemu qemu-esp qemu-gdb init # ARCH given on the command line and no TARGET: `clean` is the kernel's for that @@ -203,6 +203,10 @@ docs: fi @$(SUBMAKE) -f docs/book/Makefile BOARD=$(BOARD_DIR) BOARD_NAME=$(TARGET) +# fabric -- The Book of Fabric (#138): build/docs/BookOfFabric.pdf +fabric: + @$(SUBMAKE) -f docs/book/Makefile fabric + clean-docs: rm -rf build/docs diff --git a/docs/book/Makefile b/docs/book/Makefile index b797a48a..cc6c3d12 100644 --- a/docs/book/Makefile +++ b/docs/book/Makefile @@ -57,8 +57,15 @@ chapter_name = $(word 1,$(subst :, ,$(1))) chapter_src = $(word 2,$(subst :, ,$(1))) FRAGMENTS := $(foreach c,$(CHAPTERS),$(GEN)/$(call chapter_name,$(c)).tex) -.PHONY: all tools FORCE +# The Book of Fabric (#138): the FABRIC design record alone, as one book, from +# the same fragments -- `make fabric` -> build/docs/BookOfFabric.pdf. +FABRIC_DIR := $(OUT)/fabric +FABRIC_PDF := $(OUT)/BookOfFabric.pdf +FABRIC_FRAGS := $(foreach n,fabric-0 fabric-1 fabric-2 fabric-3 fabric-3-5 fabric-3-6 fabric-3-7 fabric-4,$(GEN)/$(n).tex) + +.PHONY: all fabric tools FORCE all: $(PDF) +fabric: $(FABRIC_PDF) tools: @missing=""; \ @@ -86,25 +93,32 @@ $(GEN)/pandoc-highlighting.tex: $(BOOK_DIR)/pandoc/highlighting.latex | tools @mkdir -p $(GEN) @printf '```c\nx\n```\n' | $(PANDOC) -f gfm -t latex -s --template=$< -o $@ -# Per-build facts the book prints: the commit every \datasource refers to, +# Per-build facts the books print: the commit every \datasource refers to, +# the version (git describe: a release's tag, or the tag and the commits since), # and which board appendix (if any) is included. -$(VAR_DIR)/meta.tex: FORCE - @mkdir -p $(VAR_DIR) +define meta_cmds + @mkdir -p $(dir $@) @{ \ c=$$(git rev-parse --short=12 HEAD 2>/dev/null || echo unknown); \ git diff --quiet HEAD -- 2>/dev/null || c="$$c (+ uncommitted changes)"; \ printf '\\newcommand{\\bookcommit}{%s}\n' "$$c"; \ printf '\\newcommand{\\bookdate}{%s}\n' "$$(date -u +%Y-%m-%d)"; \ + printf '\\newcommand{\\bookversion}{%s}\n' "$$(git describe --tags --always 2>/dev/null || echo unknown)"; \ printf '\\def\\bookboard{%s}\n' "$(BOARD_NAME)"; \ $(if $(BOARD),printf '\\newcommand{\\bookboardappendix}{board-%s}\n' "$(BOARD)";) \ } > $@.tmp @cmp -s $@.tmp $@ && rm -f $@.tmp || mv $@.tmp $@ +endef +$(VAR_DIR)/meta.tex: FORCE + $(meta_cmds) +$(FABRIC_DIR)/meta.tex: FORCE + $(meta_cmds) FORCE: TEXINPUTS_BOOK := $(abspath $(VAR_DIR)):$(abspath $(GEN)):$(abspath $(BOOK_DIR)): -$(PDF): $(BOOK_DIR)/main.tex $(FRAGMENTS) $(GEN)/pandoc-highlighting.tex $(VAR_DIR)/meta.tex | tools +$(PDF): $(BOOK_DIR)/main.tex $(BOOK_DIR)/preamble.tex $(FRAGMENTS) $(GEN)/pandoc-highlighting.tex $(VAR_DIR)/meta.tex | tools @echo " LATEXMK $(BOOK_DIR)/main.tex -> $@" @TEXINPUTS=$(TEXINPUTS_BOOK) $(LATEXMK) -xelatex -interaction=nonstopmode -halt-on-error \ -file-line-error -outdir=$(VAR_DIR) $(BOOK_DIR)/main.tex > $(VAR_DIR)/latexmk.log 2>&1 || { \ @@ -112,3 +126,14 @@ $(PDF): $(BOOK_DIR)/main.tex $(FRAGMENTS) $(GEN)/pandoc-highlighting.tex $(VAR_D echo "Error: LaTeX failed; full log: $(VAR_DIR)/main.log"; exit 1; } @cp $(VAR_DIR)/main.pdf $@ @echo " PDF $@" + +TEXINPUTS_FABRIC := $(abspath $(FABRIC_DIR)):$(abspath $(GEN)):$(abspath $(BOOK_DIR)): + +$(FABRIC_PDF): $(BOOK_DIR)/fabric.tex $(BOOK_DIR)/preamble.tex $(FABRIC_FRAGS) $(GEN)/pandoc-highlighting.tex $(FABRIC_DIR)/meta.tex | tools + @echo " LATEXMK $(BOOK_DIR)/fabric.tex -> $@" + @TEXINPUTS=$(TEXINPUTS_FABRIC) $(LATEXMK) -xelatex -interaction=nonstopmode -halt-on-error \ + -file-line-error -outdir=$(FABRIC_DIR) $(BOOK_DIR)/fabric.tex > $(FABRIC_DIR)/latexmk.log 2>&1 || { \ + grep -A4 -E '^(.*:[0-9]+:|!)' $(FABRIC_DIR)/fabric.log | head -40; \ + echo "Error: LaTeX failed; full log: $(FABRIC_DIR)/fabric.log"; exit 1; } + @cp $(FABRIC_DIR)/fabric.pdf $@ + @echo " PDF $@" diff --git a/docs/book/fabric.tex b/docs/book/fabric.tex new file mode 100644 index 00000000..f56dbdcf --- /dev/null +++ b/docs/book/fabric.tex @@ -0,0 +1,69 @@ +% docs/book/fabric.tex -- master file of The Book of Fabric (#138): the FABRIC +% design record as one book, published with every release (Captain Bob, +% 2026-11-07: "build a 'The Book of Fabric' and publish it as version +% every release"; 2026-11-08: "Publish. Fabric is all about steady +% state."). +% +% Built by `make fabric` (docs/book/Makefile) with xelatex, from the same +% pandoc fragments as the book (fabric-0 ... fabric-4, from docs/fabric/). +\documentclass[11pt,openany]{book} + +\input{preamble} + +\title{The Book of Fabric\\[0.5em]\large The StarshipOS design record} +\author{Robert A. James (Captain Bob)} +\date{Version \texttt{\bookversion}\\Built \bookdate{} from commit \texttt{\bookcommit}} + +\begin{document} +\frontmatter +\maketitle +\tableofcontents + +\chapter{About this book} +FABRIC is the design record of StarshipOS, LithosAnanke and StarForth: every +ruling, the reasoning behind it, what was built, what was found, and what was +abandoned, written as the work happened. It is reproduced here as written -- +struck-through corrections, superseded plans and all -- because the record of +what was believed, and when, is part of the record. + +One document is living at a time; when its topic closes, it is closed and a +successor opens. Part~I is the living document. Part~II holds the closed +ones, in the order they were written; each states, at its head, when and why +it closed. Part~III holds the forward-looking notes. + +Each chapter is the Markdown file named below, converted when this book is +built; the version and commit on the title page say exactly which. + +\begin{longtable}{@{}lll@{}} +\toprule +Document & Topic & Status \\ +\midrule +\endhead +FABRIC-3 & Bare metal boot & Living \\ +FABRIC-0 & The Stadium & Closed 2026-08-12 \\ +FABRIC-1 & The Stadium, continued & Closed 2026-08-25 \\ +FABRIC-2 & The Stadium, continued again & Closed 2026-09-04 \\ +FABRIC-3.5 & The Tripod/kernel reshuffle & Closed 2026-09-22 \\ +FABRIC-3.6 & The reshuffle's execution log & Closed 2026-09-22 \\ +FABRIC-3.7 & Phase 8 PKI: the elevation entrypoint & Closed 2026-10-14 \\ +FABRIC-4 & Forward-looking design notes & Notes \\ +\bottomrule +\end{longtable} + +\mainmatter + +\part{The living record} +\input{fabric-3} + +\part{The closed records} +\input{fabric-0} +\input{fabric-1} +\input{fabric-2} +\input{fabric-3-5} +\input{fabric-3-6} +\input{fabric-3-7} + +\part{Forward-looking notes} +\input{fabric-4} + +\end{document} diff --git a/docs/book/main.tex b/docs/book/main.tex index cbce2066..ab3087a1 100644 --- a/docs/book/main.tex +++ b/docs/book/main.tex @@ -6,99 +6,7 @@ % build/docs/gen/; meta.tex is generated per build. Neither is committed. \documentclass[11pt,openany]{book} -\usepackage{amsmath,amssymb} -\usepackage{fontspec} -% fonts-dejavu-core has no serif/sans italics (fonts-dejavu-extra does); when a -% shape is missing, slant the upright one rather than silently drop emphasis. -\setmainfont{DejaVu Serif}[AutoFakeSlant=0.2] -\setsansfont{DejaVu Sans}[AutoFakeSlant=0.2] -\setmonofont{DejaVu Sans Mono}[Scale=0.85] -\newfontfamily\symbolfont{DejaVu Sans} - -\usepackage[letterpaper,margin=1in]{geometry} -\usepackage{xcolor} -\usepackage{graphicx} -\usepackage{longtable,booktabs,array,calc,multirow} -\usepackage{fancyvrb} -\usepackage[normalem]{ulem} -\usepackage{enumitem} -\usepackage{newunicodechar} -\usepackage{pgfplots} -\usepackage{pgfplotstable} -\pgfplotsset{compat=1.18} -\usepackage[hidelinks]{hyperref} -\usepackage{bookmark} - -% --- what pandoc's LaTeX fragments expect (normally from its own template) -\providecommand{\tightlist}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} -\providecommand{\pandocbounded}[1]{#1} -\providecommand{\st}[1]{\sout{#1}} -\newcounter{none} % pandoc: {\def\LTcaptype{none} ...} marks unnumbered tables -\usepackage{etoolbox} -\makeatletter -\def\fnum@table{\tablename~\thetable} -\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} -\makeatother -\usepackage{fvextra} -\input{pandoc-highlighting} -% Code and diagrams are wider than the page in places: wrap, never overflow. -\RecustomVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\},breaklines,breakanywhere,fontsize=\small} -\RecustomVerbatimEnvironment{verbatim}{Verbatim}{breaklines,breakanywhere,fontsize=\small} -\setlistdepth{9} -\renewlist{itemize}{itemize}{9} -\setlist[itemize]{label=\textbullet} -\renewlist{enumerate}{enumerate}{9} -\setlist[enumerate]{label=\arabic*.} -% Running heads: chapter on the left page, section on the right, both cut to -% the page width (several design-record titles are a full sentence long). -\usepackage{fancyhdr} -\usepackage[fit]{truncate} -\pagestyle{fancy} -\fancyhf{} -\renewcommand{\chaptermark}[1]{\markboth{#1}{}} -\renewcommand{\sectionmark}[1]{\markright{#1}} -\fancyhead[LE]{\small\truncate{\dimexpr\headwidth-3em}{\leftmark}} -\fancyhead[RO]{\small\truncate{\dimexpr\headwidth-3em}{\rightmark}} -\fancyhead[RE,LO]{\small\thepage} -\renewcommand{\headrulewidth}{0.4pt} -\setlength{\headheight}{14pt} -\fancypagestyle{plain}{\fancyhf{}\fancyfoot[C]{\small\thepage}\renewcommand{\headrulewidth}{0pt}} -\setlength{\emergencystretch}{3em} -\setlength{\parindent}{0pt} -\setlength{\parskip}{0.5em} - -% --- glyphs DejaVu Serif lacks: the status marks used across the docs -\newunicodechar{✅}{{\symbolfont ✔}} -\newunicodechar{✓}{{\symbolfont ✓}} -\newunicodechar{❌}{{\symbolfont ✘}} -\newunicodechar{✗}{{\symbolfont ✗}} -\newunicodechar{⬜}{{\symbolfont ☐}} -\newunicodechar{⭐}{{\symbolfont ★}} -\newunicodechar{🔶}{{\symbolfont ◆}} -\newunicodechar{⚠}{{\symbolfont ⚠}} -\newunicodechar{📋}{} -\newunicodechar{🐛}{[bug]} -\newunicodechar{🎯}{[goal]} -\newunicodechar{🟡}{{\symbolfont ●}} -\newunicodechar{📍}{{\symbolfont ▸}} -\newunicodechar{🔓}{[unlocked]} -\newunicodechar{❓}{?} -\newunicodechar{⟺}{\ensuremath{\Longleftrightarrow}} -\newunicodechar{⋯}{\ensuremath{\cdots}} -\newunicodechar{^^^^fe0f}{} - -% --- the documents number their own sections (§III.1, D-3, ...) -\setcounter{secnumdepth}{0} -\setcounter{tocdepth}{1} - -\input{meta} - -% \datasource{path/to/data.csv}: cite the data behind a figure or table. -% Every figure or table of measured numbers reads its CSV at build time -% (\addplot table / \pgfplotstabletypeset) and is followed by this line, so -% the reader can find the exact file at the exact commit. -\newcommand{\datasource}[1]{% - \par{\small Data: \texttt{\detokenize{#1}} at commit \texttt{\bookcommit}.}\par} +\input{preamble} \title{LithosAnanke and StarForth} \author{} diff --git a/docs/book/preamble.tex b/docs/book/preamble.tex new file mode 100644 index 00000000..5483b24f --- /dev/null +++ b/docs/book/preamble.tex @@ -0,0 +1,97 @@ +% docs/book/preamble.tex -- what both books share: the packages, the fonts, +% what pandoc's fragments expect, the glyphs, the running heads, and meta.tex +% (the commit, the date, the version). Input by main.tex (the book) and +% fabric.tex (the Book of Fabric, #138). +\usepackage{amsmath,amssymb} +\usepackage{fontspec} +% fonts-dejavu-core has no serif/sans italics (fonts-dejavu-extra does); when a +% shape is missing, slant the upright one rather than silently drop emphasis. +\setmainfont{DejaVu Serif}[AutoFakeSlant=0.2] +\setsansfont{DejaVu Sans}[AutoFakeSlant=0.2] +\setmonofont{DejaVu Sans Mono}[Scale=0.85] +\newfontfamily\symbolfont{DejaVu Sans} + +\usepackage[letterpaper,margin=1in]{geometry} +\usepackage{xcolor} +\usepackage{graphicx} +\usepackage{longtable,booktabs,array,calc,multirow} +\usepackage{fancyvrb} +\usepackage[normalem]{ulem} +\usepackage{enumitem} +\usepackage{newunicodechar} +\usepackage{pgfplots} +\usepackage{pgfplotstable} +\pgfplotsset{compat=1.18} +\usepackage[hidelinks]{hyperref} +\usepackage{bookmark} + +% --- what pandoc's LaTeX fragments expect (normally from its own template) +\providecommand{\tightlist}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +\providecommand{\pandocbounded}[1]{#1} +\providecommand{\st}[1]{\sout{#1}} +\newcounter{none} % pandoc: {\def\LTcaptype{none} ...} marks unnumbered tables +\usepackage{etoolbox} +\makeatletter +\def\fnum@table{\tablename~\thetable} +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +\usepackage{fvextra} +\input{pandoc-highlighting} +% Code and diagrams are wider than the page in places: wrap, never overflow. +\RecustomVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\},breaklines,breakanywhere,fontsize=\small} +\RecustomVerbatimEnvironment{verbatim}{Verbatim}{breaklines,breakanywhere,fontsize=\small} +\setlistdepth{9} +\renewlist{itemize}{itemize}{9} +\setlist[itemize]{label=\textbullet} +\renewlist{enumerate}{enumerate}{9} +\setlist[enumerate]{label=\arabic*.} +% Running heads: chapter on the left page, section on the right, both cut to +% the page width (several design-record titles are a full sentence long). +\usepackage{fancyhdr} +\usepackage[fit]{truncate} +\pagestyle{fancy} +\fancyhf{} +\renewcommand{\chaptermark}[1]{\markboth{#1}{}} +\renewcommand{\sectionmark}[1]{\markright{#1}} +\fancyhead[LE]{\small\truncate{\dimexpr\headwidth-3em}{\leftmark}} +\fancyhead[RO]{\small\truncate{\dimexpr\headwidth-3em}{\rightmark}} +\fancyhead[RE,LO]{\small\thepage} +\renewcommand{\headrulewidth}{0.4pt} +\setlength{\headheight}{14pt} +\fancypagestyle{plain}{\fancyhf{}\fancyfoot[C]{\small\thepage}\renewcommand{\headrulewidth}{0pt}} +\setlength{\emergencystretch}{3em} +\setlength{\parindent}{0pt} +\setlength{\parskip}{0.5em} + +% --- glyphs DejaVu Serif lacks: the status marks used across the docs +\newunicodechar{✅}{{\symbolfont ✔}} +\newunicodechar{✓}{{\symbolfont ✓}} +\newunicodechar{❌}{{\symbolfont ✘}} +\newunicodechar{✗}{{\symbolfont ✗}} +\newunicodechar{⬜}{{\symbolfont ☐}} +\newunicodechar{⭐}{{\symbolfont ★}} +\newunicodechar{🔶}{{\symbolfont ◆}} +\newunicodechar{⚠}{{\symbolfont ⚠}} +\newunicodechar{📋}{} +\newunicodechar{🐛}{[bug]} +\newunicodechar{🎯}{[goal]} +\newunicodechar{🟡}{{\symbolfont ●}} +\newunicodechar{📍}{{\symbolfont ▸}} +\newunicodechar{🔓}{[unlocked]} +\newunicodechar{❓}{?} +\newunicodechar{⟺}{\ensuremath{\Longleftrightarrow}} +\newunicodechar{⋯}{\ensuremath{\cdots}} +\newunicodechar{^^^^fe0f}{} + +% --- the documents number their own sections (§III.1, D-3, ...) +\setcounter{secnumdepth}{0} +\setcounter{tocdepth}{1} + +\input{meta} + +% \datasource{path/to/data.csv}: cite the data behind a figure or table. +% Every figure or table of measured numbers reads its CSV at build time +% (\addplot table / \pgfplotstabletypeset) and is followed by this line, so +% the reader can find the exact file at the exact commit. +\newcommand{\datasource}[1]{% + \par{\small Data: \texttt{\detokenize{#1}} at commit \texttt{\bookcommit}.}\par} diff --git a/docs/v4.0.0/plans/2026-11-10-alpha4-documents.md b/docs/v4.0.0/plans/2026-11-10-alpha4-documents.md new file mode 100644 index 00000000..9b102e64 --- /dev/null +++ b/docs/v4.0.0/plans/2026-11-10-alpha4-documents.md @@ -0,0 +1,26 @@ +# alpha.4's documents and pages -- progress (kept current, one line per increment) + +Captain Bob, 2026-11-10: "Do it" -- the rest of alpha.4 that lives in the tree, after #92 (merged, +#160). #133 and #134 are the server's (Captain Bob's). + +## #138 -- The Book of Fabric +- [x] `docs/book/fabric.tex`: the FABRIC record as one book -- Part I the living record (FABRIC-3), + Part II the closed ones in order, Part III the forward-looking notes; title page with the + version (`git describe --tags`) and the commit. The book's preamble moved into + `docs/book/preamble.tex`, shared by both books (the book itself builds unchanged, 821 pages). +- [x] `make fabric` -> `build/docs/BookOfFabric.pdf` (722 pages, 42 s). +- [x] `scripts/nightly.sh docs` builds it (`$DOCS/fabric.pdf`); `publish` sends it as + `org.starship:documentation:`, classifier `fabric`; `gitea-release` attaches every + PDF in `$DOCS`, so the release carries it. + +## #157 -- the dictionary of v4, and the .com's Documents page +- [ ] the live word list of the built system (318 words) +- [ ] the table in the tree: name, stack effect, description, where defined +- [ ] the check: every live word has an entry, every entry is a live word +- [ ] the PDF, alphabetical; `make dictionary`; the nightly's docs stage, classifier `dictionary` +- [ ] the Documents page: canvas artboard, then `site/com` + +## #126 -- the Downloads page live +- [ ] `site/com` builds Downloads (and Documents) from the release: its tag, `SHA256SUMS`, the + Root CA's fingerprint +- [ ] the nav links on Home, Try it, Inquiries diff --git a/scripts/nightly.sh b/scripts/nightly.sh index c127c679..d1cbb2ce 100755 --- a/scripts/nightly.sh +++ b/scripts/nightly.sh @@ -42,7 +42,8 @@ # The book (make docs), the formal volumes (make -C docs/formal vols) and the API reference # (make -C docs/formal doxygen), into build/nightly-docs/. # scripts/nightly.sh publish-docs -# org.starship:documentation:: classifier book, vol1, vol2, vol3, api (pdf). +# org.starship:documentation:: classifier book, fabric (The Book of Fabric, #138), +# vol1, vol2, vol3, api (pdf). # # VERSION is -SNAPSHOT, or NIGHTLY_VERSION when set (a release sets it from its # tag). NEXUS_USER (default ci-publisher) and NEXUS_PASSWORD; publishing needs mvn and a JRE. @@ -173,8 +174,10 @@ publish) docs) rm -rf "$DOCS"; mkdir -p "$DOCS" make --no-print-directory docs + make --no-print-directory fabric make --no-print-directory -C docs/formal vols doxygen cp build/docs/LithosAnanke.pdf "$DOCS/book.pdf" + cp build/docs/BookOfFabric.pdf "$DOCS/fabric.pdf" for v in 1 2 3; do cp "docs/formal/build/vol$v/main.pdf" "$DOCS/vol$v.pdf"; done cp docs/formal/build/doxygen/StarForth-API-Reference.pdf "$DOCS/api.pdf" (cd "$DOCS" && sha256sum ./*.pdf | tee SHA256SUMS) @@ -217,8 +220,8 @@ print(json.dumps(notes.strip() + "\n\n## Checksums (SHA-256)\n\n```\n" + sums.st ;; publish-docs) url=${2:-}; [ -n "$url" ] || usage - need "$DOCS/book.pdf" "$DOCS/vol1.pdf" "$DOCS/vol2.pdf" "$DOCS/vol3.pdf" "$DOCS/api.pdf" - deploy "$url" documentation "$DOCS/book.pdf" pdf book \ + need "$DOCS/book.pdf" "$DOCS/fabric.pdf" "$DOCS/vol1.pdf" "$DOCS/vol2.pdf" "$DOCS/vol3.pdf" "$DOCS/api.pdf" + deploy "$url" documentation "$DOCS/book.pdf" pdf book "$DOCS/fabric.pdf" pdf fabric \ "$DOCS/vol1.pdf" pdf vol1 "$DOCS/vol2.pdf" pdf vol2 "$DOCS/vol3.pdf" pdf vol3 \ "$DOCS/api.pdf" pdf api ;;