Initial commit: Ross 1988 re-typeset edition
A searchable, re-typeset edition of Fiona Ross, "The Evolution of the Printed Bengali Character from 1778 to 1978" (Ph.D., SOAS, 1988), transcribed from the 431-leaf ProQuest scan. All 431 pages done; 178 plates and 410 inline type specimens cut from the scan; 51 errata. Tracked: the transcription (src/pages), the preamble and its typographic decisions, the cut images (plates/ — not reliably regenerable, the crop specs for the inline cuts were never scripted), tools, and the four working documents. Not tracked: the built PDF, which `make` remakes from src/ and plates/; the ProQuest scan under source/, which is third-party and needed only by `make prep` and `make plate`; scans/ and work/, both regenerable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+183
@@ -0,0 +1,183 @@
|
||||
# CONTINUATION — Ross 1988 re-typeset
|
||||
|
||||
## State (end of session 4, 2026-09-14)
|
||||
- **All 431 PDF pages transcribed.** No `\unsure` readings outstanding.
|
||||
- Chapter 5 `Vincent Figgins and Richard Watts` closed at orig. p.211 (PDF 213, notes 1–93, plates 89–96).
|
||||
- Chapter 6 `European Typefoundries` orig. pp.214–240 (PDF 216–242, notes 1–81, plates 97–105).
|
||||
- Section C `Indigenous Ventures` title at orig. p.241 (PDF 243).
|
||||
- Chapter 7 `The Girīśa Vidyāratna Press and later foundry types.` orig. pp.242–263 (PDF 244–265,
|
||||
notes 1–54, plates 106–117).
|
||||
- **Part II** `Mechanical Typefounding and Composition of Bengali` title at orig. p.266 (PDF 268).
|
||||
- Chapter 8 `Linotype Composition` orig. pp.267–308 (PDF 269–310, notes 1–124, plates 118–133).
|
||||
- Chapter 9 `Monotype Composition` orig. pp.309–337 (PDF 311–339, notes 1–54, plates 134–148).
|
||||
- **Part III** `Photocomposition of the Bengali Script` title at orig. p.338 (PDF 340).
|
||||
- Chapter 10 `Filmsetting` orig. pp.339–363 (PDF 341–365, notes 1–74, plates 149–160).
|
||||
- Chapter 11 `Digital Photocomposition` orig. pp.364–404 (PDF 366–406, notes 1–80, plates 161–174).
|
||||
- `Conclusion` orig. pp.405–410 (PDF 407–412, notes 1–19).
|
||||
- `Epilogue` orig. pp.411–418 (PDF 413–420, notes 1–14, plates 175–178).
|
||||
- `Bibliography` orig. pp.419–429 (PDF 421–431), set with the new `biblist`/`bibgroup`/`bibhead`
|
||||
macros: a bold group heading, then one entry per paragraph with a 1.6em hanging indent, set solid.
|
||||
|
||||
### Earlier state (end of session 3, 2026-09-13)
|
||||
- Building clean: **195 edition pages, 199/431 PDF pages done**. No `\unsure` readings outstanding.
|
||||
- Done (PDF pages): 1 title, 2 colophon, 3 dropped, 4–16 front matter, 17–30 Introduction (orig. pp. 15–28,
|
||||
notes 1–26, plates 1–6), 31 Part I title, 32 Section A title, 33–74 chapter 1 `Charles Wilkins`
|
||||
(orig. pp. 31–72, notes 1–131, plates 7–25).
|
||||
- **Errata section** at the end; seven entries. `\erratum` + `src/errata.tex` + `make check` keep text and list in step.
|
||||
PLAN.md's Editorial row records the policy; its Type row records the specimen rule.
|
||||
- **Inline type specimens**: 214 cut so far into `plates/inline/`, set with `\ig` at native size. Workflow per page:
|
||||
**NB `work/lines.py`'s line N is usually the line *after* the one counted visually — if a sheet comes
|
||||
back with the wrong line, try the band one earlier.**
|
||||
`work/lines.py N` lists the text lines → `work/glyphs.py N y0,y1 …` makes a numbered contact sheet of the ink
|
||||
runs on chosen lines → `tools/crop_inline.py N name=INDEX[:left|right|first|last|mid|trimright|trimleft] …`
|
||||
cuts them. When the space between a word and the glyph is too noisy to register as a gap, measure the run's
|
||||
column profile and use the `INDEX+PX` form (e.g. `48+63`).
|
||||
- **Watch for scanner bars in plate crops.** The `--rule` guard that stops engraved rules splitting a plate also
|
||||
let thin bars survive; `crop_plate.py` now sweeps any very dark thin run at an edge *after* autocropping
|
||||
(`strip_edge_bars`). Nine plates were re-cropped for this. If a plate looks like it has a black line down one
|
||||
side, that is the cause — re-run `make plate` with its recorded recipe.
|
||||
|
||||
- **Bengali policy (Sammay, 2026-09-13)**: modern script → Tiro Bangla text; a historical typeface →
|
||||
cut from the scan and set with `\ig`. Slips inside quoted matter are never corrected — mark them
|
||||
`\qslip{}` (logged to `qslips.log`) and list them in QUESTIONS.md for checking against the source.
|
||||
|
||||
|
||||
## Typography and plates — reworked 2026-09-13/14 at Sammay's request
|
||||
- **Type**: 11pt TeX Gyre ScholaX (Century Schoolbook, from `texlive-fonts-extra`, added to the Dockerfile
|
||||
for it) on a 5.2in measure ≈70 characters a line; leading 1.22; ragged right; hanging punctuation;
|
||||
`\frenchspacing`; widows/orphans forbidden; heads a step larger; endnotes smaller and tighter
|
||||
(`\notesection`); running head names the current chapter.
|
||||
- **`tools/polish.py`** runs first in `build.sh`: `src/pages` (faithful transcription, never hand-edit the
|
||||
output) → `work/pages` (what is actually typeset). It applies ties, en-dashes for ranges, small caps for
|
||||
institutional acronyms, `\mbox` round specimens, and cross-reference links. See CLAUDE.md for the full
|
||||
contract, especially the internal-vs-external rule for `p. N` references and the instruction to re-audit
|
||||
the links after changing it.
|
||||
- **Contents** and **List of Plates** entries are whole-line links to `page.N`.
|
||||
- **Plates**: `crop_plate.py` deskews an out-of-square page (rule-centre measurement, profile-variance
|
||||
fallback) and sweeps the grey gutter shadow. Deskew is the only step that resamples. All 89 plates were
|
||||
re-cropped; a sample was checked and none lost content. If a plate looks tilted or has a dark band down
|
||||
one side, re-run `make plate N=… ARGS="<recipe from the manifest>"`.
|
||||
|
||||
## Known cosmetic issue
|
||||
Three plate files (p0130, p0131, p0218) report an identical `Overfull \hbox (57.8pt)`; the rendered pages show
|
||||
no visible damage and the plates sit inside the measure. Cause not yet identified — not the image width (the
|
||||
images differ) and not the margin note (moving it outside the minipage changed nothing). The three share one
|
||||
trait: their images are **wide** enough that `width=\textwidth` (not `height=0.74\textheight`) is the binding
|
||||
constraint, so the minipage content is exactly the measure and anything else on the line tips it over.
|
||||
|
||||
## Open with Sammay — see QUESTIONS.md
|
||||
Nothing outstanding. The quotation-slip table in QUESTIONS.md lists the 15 suspected slips inside quoted
|
||||
matter, left as printed for checking against the quoted sources; it is a courtesy list, not a blocker.
|
||||
|
||||
## Next
|
||||
1. **Transcription is complete.** What remains is finishing work, not conversion:
|
||||
read the built PDF end to end for damage the per-batch spot-checks could miss;
|
||||
settle the two open QUESTIONS items (p.295 *compliments*, p.348 a dropped *to*);
|
||||
move the QUESTIONS "adopted corrections" list into the colophon.
|
||||
2. Expect more inline specimens — budget for the `lines.py` → `glyphs.py` → `crop_inline.py` loop per page.
|
||||
3. Later polish: move the QUESTIONS "adopted corrections" list into the colophon; a plate-only page's running
|
||||
head shows the previous text page too ("orig. pp. 16–38") — acceptable, refine if wanted.
|
||||
|
||||
### Never kill a build mid-run without clearing `work/main.aux`
|
||||
A full build is ~20 min at 420 pages, so the temptation is to stop one that is carrying a change you
|
||||
are about to supersede. Don't, unless you then `rm -f work/main.aux work/main.toc work/main.out`.
|
||||
`build.sh` does not clear them, so the next run reads back a `.aux` truncated mid-`\enotez@note` and
|
||||
dies at `\begin{document}` with `File ended while scanning use of \enotez@note` / `Runaway argument?`
|
||||
— an error that looks like an unbalanced brace in a page file and is not. Check
|
||||
`tail -c 200 work/main.aux` first: a clean block-boundary size (e.g. exactly 172032 bytes) ending
|
||||
mid-entry is the tell.
|
||||
|
||||
### Hyphenation — settled, do not re-open
|
||||
The original never breaks a word at a line end. Checked over all 431 leaves: 59 line-ending hyphens,
|
||||
every one a compound the author typed or OCR noise off a plate image (`work/lineend-hyphens.json`
|
||||
holds the list). Output hyphenation is therefore off (`\lefthyphenmin=62`, `\hyphenpenalty=10000`),
|
||||
with `\exhyphenpenalty` left low so a typed hyphen may still end a line as it does in the original.
|
||||
|
||||
### Unnumbered in-text figures — `\fig`
|
||||
Chapters 7 and 8 set illustrations in the run of the text with **no plate number and no caption** (the
|
||||
sentence before them carries the reference): orig. p.245's two cut/penned `ব` forms, orig. p.259's tier
|
||||
diagram. `\fig{plates/fig-pNNNN.png}` (added 2026-09-14) centres one at native size, shrinking it only if
|
||||
it is wider than the measure. Cut these by explicit pixel box with PIL — `crop_plate.py` is for whole-page
|
||||
plates — and record the box in the manifest `notes` column.
|
||||
|
||||
### A printed page number inside the plate's own column range
|
||||
Plate 119 (PDF 272) has the thesis's printed page number sitting in the same columns as the plate's lower
|
||||
figure, so no `--box` can exclude it. Crop such a plate with PIL instead: paint the page number's rectangle
|
||||
white, then take the ink bounding box. Record both steps in the manifest `notes` column.
|
||||
|
||||
### Framed plates need `--raw`
|
||||
Chapter 6's plates are reproductions of whole framed pages (`plates 97–103`). The frame's own border rules sit
|
||||
at the very edge of the crop, where `strip_edge_bars` reads them as scanner bars and sweeps them off — taking
|
||||
content with them on p0222, where two lines were lost. `crop_plate.py --raw` (added 2026-09-14) takes an
|
||||
explicit `--box` exactly: no shadow sweep, no deskew, no bar sweep, no autocrop. Measure the box first by
|
||||
finding the frame's rules (columns/rows whose ink mean exceeds 0.5), then pass `--raw --box L,T,R,B` as
|
||||
**fractions** of the raw page — `--box` is fractional, not pixels, and pixel values raise a PIL
|
||||
DecompressionBombError. Every plate recipe is in the manifest `notes` column.
|
||||
|
||||
### Measuring the original's leading — autocorrelate, don't count bands
|
||||
Counting gaps between ink bands gives nonsense: a line's ascender band and its x-height band are often
|
||||
detected separately, halving the apparent pitch, and a page with a plate or a displayed extract poisons the
|
||||
median. Pages came back at 40, 53, 70, 94 px for the same document. Autocorrelating the row-ink profile over
|
||||
the text block and taking the peak in 35-140 px is robust: every ordinary page then returns 94-95 px at
|
||||
300 dpi, and so does every specimen page. **The original is leaded 22.9 pt uniformly** — the thing to
|
||||
reproduce. Its specimens reach 16.9 pt at the 90th percentile, 74% of the line, and only 0.7% crowd it.
|
||||
Our build now measures 23.1 pt on a plain page and 23.1 pt on a specimen page (r=0.85 / 0.41; the low r is
|
||||
a seven-line block, not unevenness).
|
||||
|
||||
### First-line indent and the ragged2e trap
|
||||
The original never indents: it separates paragraphs by a blank line, and being justified, that blank line
|
||||
sits under a flush line and reads clearly. Reflowed and ragged right the cue is much weaker, so this edition
|
||||
indents 1.6em and keeps `\parskip` small (Sammay, 2026-09-14). Setting `\parindent` alone is not enough —
|
||||
ragged2e's `\RaggedRight` assigns `\parindent` from `\RaggedRightParindent` (0pt by default) every time it
|
||||
is invoked, so set both, and remember that any `\RaggedRight` inside a macro re-zeroes the indent locally.
|
||||
|
||||
### Swallowed digits: a TeX integer assignment eats the text after it
|
||||
Reported 2026-09-14: the Halhed shelfmarks on orig. p.420 came out as `- 5593`, `and 5596`, `A and 5660B`,
|
||||
`E`, `F`, `A`, `B`. The transcription in `src/pages/p0422.tex` was correct and so was `work/pages/p0422.tex`;
|
||||
the loss was in the typesetting. `biblist` set `\everypar{\hangindent=1.6em\hangafter=1}`, and `\hangafter`
|
||||
is an integer parameter: TeX goes on scanning digits after the `1`, so a paragraph beginning `5590 - 5593`
|
||||
assigned `\hangafter=15590` and the number was gone. Fixed by terminating the assignment with `\relax`.
|
||||
**Any numeric assignment in an `\everypar`, a hook, or a macro that can be followed by body text needs
|
||||
`\relax`.**
|
||||
|
||||
### One build at a time in `work/`
|
||||
`build.sh` runs every pass in `work/`, so two concurrent `make build`s share `main.aux`. Starting a second
|
||||
build (or clearing the aux files by hand) while one is running kills the first at `\end{document}` with
|
||||
"I can't find file `main.aux'", and the next pass dies at `\begin{document}` in `\openout\@mainaux` — which
|
||||
looks like a permissions or disk fault and is neither. Wait for the running build before starting another.
|
||||
|
||||
### A group that ends before its own `\par` loses its leading
|
||||
Twice now: the plate captions, and the last paragraph of `src/colophon.tex`. `\setstretch` (like `\small`)
|
||||
is a paragraph-shape parameter read at the `\par` that ends the paragraph, so `{\setstretch{1.2} text}` or
|
||||
`\begingroup\setstretch{1.2} ... \endgroup` sets the final paragraph at the *outer* leading. End the
|
||||
paragraph explicitly — `\par` before the closing brace or `\endgroup`.
|
||||
|
||||
### `tools/reprocheck.py` — the reproduction check that found it
|
||||
Bag comparison, not sequence: every token in `src/pages/*.tex` must reach the built PDF at least as often as
|
||||
it appears in the source. Order-insensitive, because endnotes and the Contents move text about. Run it after
|
||||
any build that changes the preamble:
|
||||
|
||||
python3 tools/reprocheck.py [pdf]
|
||||
|
||||
It de-TeXes the page files (macro table in the script says which argument of each macro carries copy) and
|
||||
compares against `pdftotext -layout`. Two extraction artifacts are reported separately as "merged into a
|
||||
neighbour", not as losses: poppler glues an endnote superscript onto the word before it (`em.`+`55`), and it
|
||||
drops the thin space between the two Bengali forms in a Scheme-of-Transliteration cell. `-layout` is required
|
||||
— without it poppler rejoins a compound broken at its own hyphen (`Staats-Druckerei`), which this text does
|
||||
constantly, and ~80 false positives appear. A clean run prints `0 tokens short`.
|
||||
|
||||
## Environment
|
||||
Runs from this directory with Claude Code; tools via `make` (Docker). `CLAUDE.md` has the rules and macro table.
|
||||
The Makefile exports `UID`/`GID` (zsh does not). `make check` and `make build` must both pass at the end of
|
||||
every batch.
|
||||
|
||||
## Layout
|
||||
```
|
||||
ross-thesis/
|
||||
PLAN.md CONTINUATION.md QUESTIONS.md manifest.tsv build.sh
|
||||
src/preamble.tex src/colophon.tex src/errata.tex src/main.tex (generated) src/pages/pNNNN.tex
|
||||
tools/prep.sh tools/ocr2tex.py tools/crop_plate.py tools/crop_inline.py tools/check.py tools/setrow.py tools/reprocheck.py
|
||||
work/lines.py work/glyphs.py (scratch helpers for the specimen workflow)
|
||||
fonts/TiroBangla-*.ttf plates/pNNNN.png plates/inline/pNNNN-*.png plates/logo-proquest.png
|
||||
scans/ work/ (scratch; excluded from tarball) older-versions/ ross-1988-retypeset.pdf
|
||||
```
|
||||
Reference in New Issue
Block a user