Verbatim-safe typography, ^-punctuation quoting, full-range ^UUUU^, polyglot html

Typographic transforms (---, quote pairs, ~) no longer touch verbatim
text: @c/@code/@source_listing content and ^'...'^ spans show exactly the
characters written. "^" before any punctuation character quotes it in
every target (the apostrophe excepted: ^' opens a literal span), with the
new :resolve option on @@@target declaring per-target renderings. The
^UUUU^ code-point form accepts 4-6 hex digits, the full Unicode range.
The html output and transform spellings are polyglot (XML-valid), in
preparation for an EPUB target. New suites: transform_test, character_test
(engine), typography_test (SKS).

(from dev 07ce5ea86a0a)
This commit is contained in:
2026-08-23 20:48:26 +02:00
parent d982c0d6cc
commit 37b6ba1c4f
77 changed files with 1665 additions and 1608 deletions

View File

@@ -9,49 +9,77 @@ paragraph pass recognizes as a block and leaves alone, and \par in
vertical mode is a no-op.
]#
@@par.k s : A paragraph of text @@
# Paragraph
@@par.k s : A paragraph of text. @@
@@par.html :: <p>*s*</p> @@
@@par.tex ::
\par
*s*
\par
@@
@@par.tex :: \par *s* \par @@
# In plain text a paragraph is delimited by blank lines, which
# phases.justify_blocks then fills; #/2 inserts them without depending on
# the definition body's own whitespace surviving extraction.
@@par.txt :: #/2*s*#/2 @@
# Non-breaking space
@@sp.k : Non-breaking space character @@
@@sp.html :: &^#160; @@
@@sp.tex :: ~ @@
# TODO: Easy in LaTeX; how to handle in HTML and plain text?
# @@footnote.k s : Footnote (TBD) @@
# @@footnote :: [*s*] @@
# Indented block
@@indent.k s :w.int 3 :linebreak.bool false : Indented block @@
@@indent.k s :left.int 8 :right.int -1 :ragged.bool false :
Indented block. The *left* and *right* values are the number of characters for
indentation (as roughtly defined by "ex"). By default, *right* is set to the
*left* value (with -1 as the sentinel).
@@
@@indent.html,tex,txt :: @eval block.Indent(K) eval@ @@
@@quote.k s :w.int 1 :source : Quotation block @@
@@quote.html ::
<div class="quote">
# Right justification
@@right.k s :margin 0 :top_margin 2 : Right-justified text @@
@@right.html ::
<div style="text-align: right; margin: *top_margin*ex *margin*ex 2ex 0;">*s*</div>
@@
@@right.tex ::
{\setlength{\topsep}{0pt}\setlength{\partopsep}{0pt}\setlength{\parskip}{*top_margin*ex}
\begin{flushright}
\raggedleft\rightskip=*margin*ex
*s*
</div>
\end{flushright}}
@@
@@quote.tex ::
\quoteblock{*s*}{*source*}
@@right.txt ::
@eval import textwrap; "\n".join([line.rjust(*Target_txt_width*, "~")
for line in textwrap.wrap("""*s*""", *Target_txt_width*)]) @
@@
@@quote.txt ::
@eval block.block_indent(K) eval@
@@
@@note.k s :label Note :color 1.0,1.0,0.9 :bordercolor 0.2,0.2,0.2 :level.int 0 :width
: Rectangular block for a special note @@
# Quote with attribution
@@note.html,tex :: @eval block.Note(K) eval@ @@
@@quote.k text | attribution : A block quote with attribution. @@
@@quote.html,tex ::
@indent *text* :left 8 @
@right *attribution* :margin 8
:top_margin @cond @eval "*K_target*" == "html" @ | -1 | 1 cond@ @
@@
# Highlighted note in text
@@note.k s :label Note :color 1.0,1.0,0.9 :border_color 0.2,0.2,0.2 :level.int 0 :width.float 0.5
: Rectangular block for an editorial note @@
@@note.html,tex :: @eval block.Note(K) @ @@
# Center
@@center.k s : Center text @@
@@ -62,42 +90,46 @@ vertical mode is a no-op.
@@
@@center.html ::
<p>
<div class="center">
*s*
</div>
</p>
@@
@@right.k s : Right-justified text @@
@@right.html ::
<b>TBD</b> *s*
@@
@@right.tex ::
\begin{flushright}
*s*
\end{flushright}
@@
# Newline
@@nl.k : Newline character @@
@@nl.html :: <br> @@
@@nl.html :: <br/> @@
@@nl.tex :: \newline @@
@@nl.txt :: \n @@
@@nl.txt :: @eval phases.txt_nl_marker() @ @@
# New page
@@newpage.k : Start new page @@
@@newpage.html :: @@
@@newpage.tex :: \newpage @@
@@newpage.txt :: @@
# Extend page
@@extendpage.k linecount : Extenad current page @@
@@extendpage.html :: @@
@@extendpage.tex :: \enlargethispage{*linecount*\baselineskip} @@
@@extendpage.txt :: @@
# Vertical space
@@vspace.k lines.float : Vertical space, in multiples of the current line height @@
@@vspace.tex :: \vspace{*lines*\baselineskip} @@
@@vspace.html :: <div style="height: *lines*lh"></div> @@
@@vspace.txt :: @eval "__VSPACE__" * round(*lines*) @ @@
@@vspace.txt :: @eval phases.txt_vspace_marker() * round(*lines*) @ @@
# Vertical fill to end of page
@@vfill.k :
Fill the vertical space so that any following text is flush with the bottom
@@ -112,6 +144,8 @@ only makes some vertical space. @@
@@vfill.txt :: @vspace 3 @ @@
# Questions and answers
@@qa.k question | answer : Question and answer formatting @@
@@qa.html,tex,txt ::
@b Q: @ *question*
@@ -119,6 +153,9 @@ only makes some vertical space. @@
@b A: @ *answer*
@@
# Absolute positioning
@@@argtype coords | x and y coordinates :pattern 'float'\s+'float' @@@
@@block.k : to.coords | content :width.float .5 :point.coords 0.0 0.0
@@ -126,18 +163,51 @@ only makes some vertical space. @@
@@block.tex :: @eval block.Block(K) eval@ @@
# Preserved line endings
@@lines.k s : Maintain line breaks @@
@@lines.html,tex,txt :: @eval block.Lines(K) eval@ @@
@@twocolumns.k s : Format *s* in two columns @@
@@twocolumns.tex ::
\begin{multicols}{2}
# Multiple columns of text
@@multicolumn.k s :n 2 :gap 3 : Format *s* in *n* columns (default: 2). The *gap* is in "ex" units. @@
@@multicolumn.tex ::
{\setlength{\columnsep}{*gap*ex}
\setlength{\multicolsep}{\parskip}
\begin{multicols}{*n*}
*s*
\end{multicols}
\end{multicols}}
@@
@@left_right.k left | right : Text left- and right- justified on one line @@
@@left_right.tex ::
\makebox[\dimexpr\linewidth+\labelindent\relax]{*left*\hfill *right*}
@@multicolumn.html ::
<p>
<div style="column-count: *n*; column-gap: *gap*ex; text-align: justify;">
*s*
</div>
</p>
@@
# Text justified left and right on one line
@@left_right.k parts.rest(2) :
Pairs of text left- and right- justified. First, left lines are written with a
bar (|) between each line. Then, two bars (||), and the right lines with a bar
betwen them.
@@
@@left_right.html,tex :: @eval block.Left_right(K) @ @@
# Footnote
@@footnote.k s : Footnote @@
@@footnote.html :: <kt-footnote>*s*</kt-footnote> @@
@@footnote.tex :: \unskip\footnote{*s*} @@
@@footnote.txt :: __ #- @eval phases.txt_footnote_marker() @ *s* @eval phases.txt_footnote_marker() @ #- __ @@
# This doesn't work, either, so it isn't the @eval:
# @@footnote.txt :: __ #- marker *s* marker #- __ @@