A run of Unicode code points now needs one pair of carets, not one pair
each: ^9053 53EF 9053^ renders the characters adjacently, and a single
character inside such a run stands for itself. An invalid code point is
an error naming the position that wrote it, rather than an apology
rendered into the finished document; noncharacters are refused alongside
surrogates; and a code point that lands on a Klammertext special is safe
through the re-reads that assemble a document. The character tables now
produce the precomposed form, so a diacritic written as ^a" and one typed
directly are the same text to a search or a copy-paste.
"kdesc -u" describes how to write a Unicode character, with tables of
glyphs beside the codes that produce them. It is new and not yet
complete: it predates the sequence form and the typeface klammer below.
A typeface and a style are no longer both called "font". A typeface is a
family resolved by name; a style code is the one letter naming a type
style. So @document takes :serif_typeface and its siblings, a table takes
:style, captions take :caption_style and :caption_size, the uniform scale
is :text_scale, and the command is "kdesc --typeface". This renames
arguments a document may already use; an old name is a located error
rather than a silent omission.
@typeface sets a passage in another typeface for the length of that
passage:
@typeface Noto Sans Egyptian Hieroglyphs | ^132AA 133CF^ :scale 1.5 @
Writing the klammer is the whole declaration -- the document resolves the
typeface, embeds it in what it produces, and carries its license along.
Two typefaces for scripts no text font covers now ship with Klammertext:
Noto Sans Egyptian Hieroglyphs and Noto Sans Cuneiform. Every typeface in
the distribution now carries its license file.
(from dev 61e598698891)
113 lines
4.5 KiB
Python
113 lines
4.5 KiB
Python
import re
|
|
import klammer_base
|
|
|
|
class Subsuper(klammer_base.Klammer_base):
|
|
def __init__(self, K, position):
|
|
super().__init__(K)
|
|
self.position = position
|
|
"""
|
|
print("Subsuper:", self.args)
|
|
|
|
parts = self.args.strip().split()
|
|
if len(parts) != 2:
|
|
raise Exception(f"Two arguments required, but argument is: {self.args.strip()}")
|
|
self.base, self.script = parts
|
|
"""
|
|
|
|
def html(self):
|
|
return f"{self.base}<{self.position}>{self.script}</sub>"
|
|
|
|
def tex(self):
|
|
if self.position == "sub":
|
|
return f"${self.base}_{self.script}$"
|
|
else:
|
|
return f"${self.base}^{self.script}$"
|
|
|
|
# The typeface-declaration marker. A klammer cannot declare a typeface
|
|
# itself: in html the @font-face must be in the page's css and the files
|
|
# localized into <output>/fonts/, and in tex the \newfontfamily must be in
|
|
# the preamble -- both are @document's, and @document runs AFTER the
|
|
# klammers it contains (application is post-order). So @typeface leaves
|
|
# this marker where the typeface is needed, and @document collects the
|
|
# markers, resolves and localizes each typeface, declares it, and replaces
|
|
# the marker with whatever inline switch the target needs (a font-switch
|
|
# command for tex, nothing for html, which carries the family name in the
|
|
# span's own style). Same shape as the __CAPTION__ markers.
|
|
#
|
|
# SYNC: typeface_marker_rgx in sks/document/document_class.h -- a C++/Python
|
|
# pair, so the constant cannot be single-sourced the way a .k/.py pair can
|
|
# (TODO #47); change both or neither.
|
|
def typeface_marker(name, scale):
|
|
return f"__TYPEFACE__{name}__{scale}__"
|
|
|
|
class Typeface(klammer_base.Klammer_base):
|
|
"""A temporary typeface change (@typeface). See sks/font/font.k."""
|
|
|
|
def __init__(self, K):
|
|
super().__init__(K)
|
|
|
|
def html(self):
|
|
# font-size-adjust is switched OFF for the span: the document
|
|
# normalizes families to a common x-height (font.css), which is
|
|
# meaningless for a script whose glyphs have no x-height at all --
|
|
# hieroglyphs, cuneiform -- and would resize them unpredictably.
|
|
# The family name is quoted -- an unquoted digit-initial word
|
|
# ("Source Sans 3") is invalid CSS -- with SINGLE quotes, because
|
|
# this sits inside a double-quoted html attribute.
|
|
style = (f"font-family: '{self.name}', serif; "
|
|
f"font-size-adjust: none")
|
|
if float(self.scale) != 1.0:
|
|
style += f"; font-size: {float(self.scale)}em"
|
|
# 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 TEXT is
|
|
# writer content and is deliberately left alone -- its quotes and
|
|
# dashes should be transformed.
|
|
return (typeface_marker(self.name, self.scale)
|
|
+ f'<span style="{klammer_base.hide_typographic(style)}">'
|
|
+ f'{self.text}</span>')
|
|
|
|
def tex(self):
|
|
# The marker becomes the font-switch command; the group is what
|
|
# 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 + "}"
|
|
|
|
def txt(self):
|
|
# A typeface cannot be expressed in plain text. Declared in the
|
|
# .k description, so this is documented behaviour rather than a
|
|
# silent per-target divergence.
|
|
return self.text
|
|
|
|
def html_fontify(text, font_symbol, font_size):
|
|
cls = {"r" : "",
|
|
"i" :"ritalic",
|
|
"b" : "bold",
|
|
"s" : "sansserif",
|
|
"t" : "monospace",
|
|
"c" : "code"}[font_symbol]
|
|
result = text
|
|
if cls:
|
|
if font_symbol == "c":
|
|
result = re.sub(" ", " ", result)
|
|
cls = f'class="{cls}"'
|
|
sty = ""
|
|
if font_size != 1:
|
|
sty = f'style="font-size: {float(font_size) * 100}%"'
|
|
attr = (cls + " " + sty).strip()
|
|
if attr:
|
|
result = f'<span {attr}>{result}</span>'
|
|
return result
|
|
|
|
|
|
def tex_fontify(text, font_symbol, font_size):
|
|
command = {"r" : "\\rmfamily",
|
|
"i" :"\\it",
|
|
"b" : "\\bfseries",
|
|
"s" : "\\sffamily",
|
|
"t" : "\\ttfamily",
|
|
"c" : "\\ttfamily"}[font_symbol]
|
|
result = f"{{{command}\\scalefont{{{font_size}}}{{{text}}}}}"
|
|
return result
|