v0.25.0 — Zero-configuration shipping: an embedded core, and an installation that finds itself
A minor release about shipping: texish now works as a plain library dependency with nothing installed and
nothing configured, and an installed copy finds its own fonts and packages without an environment variable.
Getting there meant deciding what belongs inside the artifact and what does not, which is where the breaking
changes come from.
Nothing to configure
The core is compiled into the artifact as base64 and is there on every platform:
- Latin Modern — the roman body with its bold, italic, slanted and small-caps cuts, plus the sans and
typewriter roles. - Latin Modern Math — the default math font.
- New Computer Modern, all four cuts — the glyph-fallback face.
- JetBrains Mono, regular and bold — the face
\codesets a listing in.
Plus the base and document packages. So a program that adds texish as a dependency and configures nothing
sets an ordinary document: Latin, Greek, Cyrillic, mathematics, syntax-highlighted source code.
Two of those were shipping broken before and nobody had noticed. Glyph fallback is configured from New
Computer Modern, which was not embedded, so every zero-configuration install drew missing-glyph boxes for
the first Greek or Cyrillic word. And \code's TextMate grammars were compiled in while the face they are
drawn in was not, so any document with a listing failed outright — including the project's own flagship demo.
Both were found by rendering every demo against a binary with no font tree beside it, which is a thing the
1500-test suite structurally cannot catch.
An installation finds itself
A packaged texish locates its own executable and looks upward for a share/texish/ directory, or a fonts/
and packages/ beside it. A package needs no wrapper script and no environment variable — bin.install
and share.install is the whole formula. It works the same invoked by absolute path, through $PATH, or
through a package manager's link farm.
Install.configure() is in the Native library rather than in the command-line tool, because the tool is not
the only program that needs it: an application embedding texish, whose package depends on texish's, has the
same question to answer. It searches from the executable path both as reached and as symlink-resolved, which
are two different installations — the resolved path lands in the versioned directory holding a program's own
data, while the path as reached lands in the shared prefix, which is the only way a program finds files
belonging to a different package.
$TEXISHHOME still works, as a fallback for a tree in neither place.
Fonts: a core and a catalogue
The full bundled set is 151MB, far too much to compile in, so it stays on disk and a host asks for it:
Typesetter.home = "/opt/texish" // where the fonts/ and packages/ live
val t = new CairoPDFTypesetter("out.pdf")
t.loadBundledCatalogue() // then ask for the familiesFontSource replaces the ad-hoc root probing. A source answers with a file or with bytes, whichever it holds,
and a file wins where both are available since a backend reads a face from a path lazily. registerFontSource
and clearFontSources are the general form; Typesetter.home is the one-liner.
Loading the catalogue is tolerant, because a font tree may be partial — and it now records what it skipped, so
a missing family gets a diagnostic that points at the installation rather than at the document:
typeface 'hebrew' is one texish bundles, but its font files were not found —
no font source has 'fonts/NotoSerifHebrew/NotoSerifHebrew-Regular.ttf'
Naming a bundled family when the catalogue was never loaded says that instead, and a name texish does not
bundle still gets the bare "not found". The three are fixed in three different places, so they read
differently.
Mathematics needs no package
The math package is gone; its eleven macros are built into the engine. The line it drew through the standard
operator set was arbitrary — \tan built in, \arctan not — and eight of the eleven were plain LaTeX rather
than the amsmath additions the package claimed to supply.
\arcsin, \arccos, \arctan and \Pr join the standard operator names (\Pr with limits, like \max).
\bmod is an upright binary "mod"; \pmod{m}, \mod{m} and \pod{m} set a congruence's modulus off by a
quad. \implies, \impliedby and \iff are heavy arrows with a thick space on either side. $\arcsin x$
needs no preamble.
Fixes
- Footnotes were set in literal black rather than the document's ink, so a document with a coloured pen
had black footnotes. They now take the colour in force where the footnote sits. - Uncoloured picture marks were black too — an arrow, arrowhead or placed glyph with no
\strokeor
\fillof its own fell back to a fixed black instead of the pen. A picture that names no colour now draws
in the document's ink and follows it into a dark scheme. \loadfontnow resolves a relative path against the document's own directory, so a font kept beside the
document is found however the host was launched.- A
\loadfontnaming a file nothing has is an error rather than a silently registered face over a bad
path.
Breaking changes
Typesetter.fontsDiris nowTypesetter.home. It names a directory holding bothfonts/and
packages/— the programmatic$TEXISHHOME— and is consulted by the font search and by\usealike.TEXISH_FONTS_DIRis gone.TEXISHHOMEis the only environment variable, and is now a fallback rather
than the documented route.\use{math}no longer resolves. Delete the line; everything it defined is built in.- Only
baseanddocumentare compiled into the artifact. Every other package —diagram,plot,
book,usfm,railroad,music, … — resolves from apackages/folder on disk. An installed texish
finds it automatically; a library consumer needsTypesetter.home. - The bundled font families beyond the core are opt-in, through
loadBundledCatalogue(). The
command-line tool calls it for you. - The SMuFL music faces are catalogue fonts, and
musicis not embedded, so the two travel together. - Scala.js is no longer in the cross-build. The browser backends are kept on disk and in git, and
build.sbt, the README and the browser guide all say how to bring them back; the effort of keeping a third
platform green was not paying for itself.