txt section numbering, @typeface :middle/:lift and html scale, NewGardinerOmni, html :leading (from dev 9fa469dd74ed)
Section headings under txt are numbered inside a @document only; @typeface gains :middle and :lift and its :scale now means the same in html and pdf; NewGardinerOmni ships (OFL 1.1, Mark-Jan Nederhof) and @egyptian / @chinese replace @cjk; @table :leading and :colsep reach html; kdesc --typeface help names the flag; @document.txt is a Python class. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
0ead40f272
commit
63956c00e5
26 files changed
+437
-173
No files matched your search
+29
-4
@@ -26,13 +26,28 @@ font as document text instead of setting anything. @typeface is the
|
||||
temporary, all-target replacement.
|
||||
]#
|
||||
|
||||
@@typeface.k name | text :scale.float 1.0 :
|
||||
@@typeface.k name | text :scale.float 1.0 :middle.bool :lift.length :
|
||||
A temporary change of typeface for *text*: the typeface *name* is
|
||||
resolved in the Klammertext font store (the directories of
|
||||
KLAMMERTEXT_FONTS, then the distribution's own), and the document
|
||||
declares and localizes it automatically -- writing this klammer is the
|
||||
only declaration needed. *scale* multiplies the surrounding text size,
|
||||
which a script whose glyphs are drawn small usually wants.
|
||||
only declaration needed. *scale* multiplies the size of the surrounding
|
||||
text as it appears, the same in html and pdf, which a script whose glyphs
|
||||
are drawn small usually wants.
|
||||
|
||||
*middle* centres *text* on the surrounding line instead of standing it on
|
||||
the baseline -- for a script with no baseline relationship to the text,
|
||||
such as hieroglyphs, whose font declares a tall ascender that would
|
||||
otherwise open up every line the glyphs sit in. Html only: in tex a
|
||||
row is already as tight as its tallest glyph. Never for a Latin
|
||||
typeface, whose baseline must stay shared with the text around it.
|
||||
|
||||
*lift* shifts *text* up by a length (down when negative), in em, pt or
|
||||
px -- the correction for a font that draws its glyphs off the baseline,
|
||||
which is a property of the font and so belongs in the klammer that names
|
||||
it: Noto Sans Egyptian Hieroglyphs floats its signs and wants about
|
||||
0.15em, NewGardinerOmni stands them on the baseline and wants none.
|
||||
Html and tex alike; the txt target has no vertical position.
|
||||
|
||||
The change ends with *text*: nothing after it is affected. Under the
|
||||
txt target a typeface cannot be expressed at all, so *text* is emitted
|
||||
@@ -107,9 +122,19 @@ than a typeface -- xeCJK for the tex path), so this klammer errors with
|
||||
the list of available typefaces until one is installed with
|
||||
"kdesc --typeface install". That is the honest behaviour: the klammer
|
||||
states what it needs and the store reports what it has.
|
||||
]#
|
||||
@@cjk.k text : Set *text* in a typeface that supports CJK @@
|
||||
@@cjk.html,tex,txt :: @typeface Noto Sans CJK SC | *text* @ @@
|
||||
]#
|
||||
|
||||
# Only defining on Chinese style for now; could be parameterized.
|
||||
@@chinese.k text :scale.float 1 : Set *text* in a Chinese font @@
|
||||
@@chinese.html,tex,txt :: @typeface Noto Serif SC :scale *scale* | *text* @ @@
|
||||
|
||||
# Egyptian hieroglyphs
|
||||
@@egyptian.k text :scale.float 1.75 : Set *text* in an Egyptian hieroglyph font @@
|
||||
@@egyptian.html,tex,txt :: @typeface NewGardinerOmni :scale *scale* :middle | *text* @ @@
|
||||
# @@egyptian.html,tex,txt :: @typeface Noto Sans Egyptian Hieroglyphs :scale *scale* :middle | *text* @ @@
|
||||
|
||||
|
||||
@@fraktur.k s : Set text *s* in Fraktur @@
|
||||
@@fraktur.tex :: \textfrak{*s*} @@
|
||||
|
||||
+52
-3
@@ -60,9 +60,38 @@ class Typeface(klammer_base.Klammer_base):
|
||||
# this sits inside a double-quoted html attribute. What is quoted
|
||||
# here is the MARKER: @document replaces it with the resolved
|
||||
# family name (see the marker note above).
|
||||
# The size is the scale times the body's own enlargement: the body
|
||||
# is rendered at "font-size-adjust: ex-height 0.5" (font.css), so
|
||||
# the visible text is larger than its nominal size, and a span
|
||||
# with the adjust off at a plain "Nem" sat about a fifth smaller
|
||||
# against it than the same :scale in pdf. @document emits the
|
||||
# factor as --typeface_scale (document_html.cpp, font_definitions);
|
||||
# the fallback 1 is for a fragment rendered without @document.
|
||||
# The "*" of calc() survives the @eval re-read (tested 2026-09-18);
|
||||
# the "--" of the property name is hidden below with the rest.
|
||||
style = "', serif; font-size-adjust: none"
|
||||
if float(self.scale) != 1.0:
|
||||
style += f"; font-size: {float(self.scale)}em"
|
||||
style += f"; font-size: calc({float(self.scale)}em * var(--typeface_scale, 1))"
|
||||
# :middle -- for a script with no baseline relationship to the
|
||||
# text. A browser sizes the span's inline box from the FONT's
|
||||
# ascender and descender, not the glyph's ink, and centres it on
|
||||
# the content area's midpoint; a hieroglyph font declares an
|
||||
# ascender of 1.0 em and no descender (NewGardinerOmni; Noto:
|
||||
# 1.324/-0.326), so at :scale 1.75 the box sat half an em too
|
||||
# high and every table row grew from 31 to 47 px (Noto: 62).
|
||||
# line-height 1 drops the body's leading from the enlarged box and
|
||||
# vertical-align middle centres it on the PARENT's x-height, which
|
||||
# is why this uses the text's metrics, not the script font's zeros.
|
||||
# Measured 2026-09-18: 40 px, the floor the ink allows; line-height
|
||||
# 0 alone gave 31 px with the glyphs overlapping the rows above.
|
||||
# Off by default: a Latin typeface must keep the shared baseline.
|
||||
if self.middle:
|
||||
style += "; line-height: 1; vertical-align: middle"
|
||||
if self.lift_length():
|
||||
# Relative positioning moves the ink and nothing else: the
|
||||
# line box is laid out as if the span had not moved, which is
|
||||
# what a baseline correction wants (vertical-align would
|
||||
# re-lay the line). Negative top = up, as \raisebox in tex.
|
||||
style += f"; position: relative; top: -{self.lift_length()}"
|
||||
# The STYLE is markup, so its typographically active characters are
|
||||
# hidden: the html target's transforms turn a single quote into a
|
||||
# curly one, which broke the css font-family value. The MARKER is
|
||||
@@ -81,7 +110,27 @@ class Typeface(klammer_base.Klammer_base):
|
||||
# makes the change temporary (the retired @font emitted a bare
|
||||
# \setmainfont, which changed the font for the rest of the
|
||||
# document).
|
||||
return "{" + typeface_marker(self.name, self.scale) + " " + self.text + "}"
|
||||
group = "{" + typeface_marker(self.name, self.scale) + " " + self.text + "}"
|
||||
if self.lift_length():
|
||||
# A \raisebox produced HERE is safe from the generator escaping
|
||||
# pass: this klammer is applied after a generator's result has
|
||||
# been escaped, so its backslash is never swept -- the trap
|
||||
# @nl.tex fell into (2026-09-07) is a klammer applied inside a
|
||||
# generator's ARGUMENT, which @typeface shares with @b and @i.
|
||||
return "\\raisebox{" + self.lift_length() + "}" + group
|
||||
return group
|
||||
|
||||
def lift_length(self):
|
||||
# :lift, validated to the units both targets can move by. The
|
||||
# length argtype admits w/h fractions and a quoted string, which
|
||||
# mean nothing as a vertical shift; a bare number would be columns
|
||||
# or lines and is refused for the same reason.
|
||||
lift = self.lift
|
||||
if not lift:
|
||||
return ""
|
||||
if not re.fullmatch(r"-?(\d+\.?\d*|\.\d+)(em|pt|px)", lift):
|
||||
raise Exception(f"@typeface :lift takes a length in em, pt or px, not '{lift}'")
|
||||
return lift
|
||||
|
||||
def txt(self):
|
||||
# A typeface cannot be expressed in plain text. Declared in the
|
||||
|
||||
Reference in new issue
Block a user