Files
klammertext/sks/block/block.py
Andy Kopra 59c1599bc9 Target coverage: a klammer states the targets it serves
kdesc gains --coverage, which reports for every klammer the set of targets it
can render to, and — the point of it — which klammers' coverage cannot be
derived and must therefore be declared.  Three rules: coverage is DERIVED
where the definitions determine it (a general body of klammer calls covers
the intersection of what those klammers cover, by a greatest fixpoint after
loading), DECLARED where the engine cannot interpret what decides it (an
@eval body, whose targets are undecidable), and UNKNOWN where nothing is
written — which never means "deliberately unavailable".

Two new spellings in a definition's name.  A comma-separated target list,
"@@table.html,tex :: ...", gives one body several targets; it is surface
syntax, expanded at registration, and each member goes through the
redefinition rules on its own.  And "@@date.* :: ..." writes the general
target out, asserting that the klammer works for EVERY target including ones
not yet defined — a stronger claim than a list of the targets defined today,
and the one target declaration that could be mechanically falsified.

The Standard Klammer Set was swept accordingly: it now has no general
definitions at all, every klammer names the targets it serves, six use ".*",
and tex and pdf are at zero undecided.

kdesc's flags are reorganised on two rules: a flag reached for often gets a
single letter (-k klammers, -t targets, -c characters, -i input), a more
specialised topic a multi-letter name (--argtypes, --katoms, --rewrite,
--optionsets, --coverage, --klammerset, --font); and -v says how much to show
about PROCESSING, never what the RESULT contains — so the katom regex column
is "--katoms full" and the coverage detail "--coverage all".  NOTE: "-k" now
lists klammers (optionally filtered by a name/description search); the katom
table moved to "--katoms".

Fixes carried along: an option written with no value crashed the command with
SIGSEGV instead of reporting the mistake; two required positional arguments
never parsed; kdesc and kdiag printed an error and exited 0; and definition
diagnostics counted registrations rather than what was written, so one line
could be reported as two definitions and then printed twice.

Four new test suites: target_list, coverage, command_option, kdesc.

(from dev 46f54080bd9a)
2026-08-12 17:20:23 +02:00

112 lines
3.5 KiB
Python

import re
import textwrap
import pprint
import klammer_base
import kutil
import latex_util
class Indent(klammer_base.Klammer_base):
def __init__(self, K):
super().__init__(K)
self.s = kutil.escape(self.s)
def html(self):
return "FIX: INDENT " + self.s
def tex(self):
tab = f"\\hspace*{{{self.w}ex}}"
result = ""
if self.linebreak:
for e in self.s.split("\n"):
result += f"{tab}{e}\\\\\n"
result = result[:-3]
result = re.sub(r"\t", r"\\t", result)
else:
result = tab + latex_util.minipage(
"\\raggedright " + self.s, f"\\textwidth - {self.w}ex", center=False, vmargin="4pt")
#print(result)
return latex_util.block(result)
def txt(self):
indent = " " * self.w
result = self.s
result = re.sub("KK0022", '"', result)
result = indent + f"\n{indent}".join(textwrap.wrap(result, width=70, break_on_hyphens=False))
return f"@lit\n{result}\nlit@"
class Note(klammer_base.Klammer_base):
def __init__(self, K):
super().__init__(K)
def html(self):
color = ",".join([f"{float(e)*100}%" for e in self.color.split(",")])
result = f'''<div class="box" style="background-color: rgb({color}); border-color: rgb({self.bordercolor}) ;">
<b>{self.label}:</b> {self.s}
</div>'''
return result
def tex(self):
if self.width:
width = r'{}\\textwidth'.format(self.width)
else:
#width = r'\\textwidth - 16pt - {}\\leftmargin'.format(self.level)
width = r'\\linewidth - \\leftmargin + 2pt'
# The \par on each side comes from latex_util.block() below: an
# \fcolorbox is box material and must sit in vertical mode.
result = '''
\\begingroup
COLOR\\setlength{\\fboxsep}{8pt}
\\fcolorbox{bordercolor}{localcolor}{
\\parbox{WIDTH}{\\raggedright\\setlength{\\parskip}{8pt}
\\textbf{LABEL:} TEXT
}}\\endgroup
'''
result = re.sub('LABEL', self.label, result)
result = re.sub('TEXT', re.sub(r'\\', r'\\\\', self.s), result)
result = re.sub('COLOR', r'\\definecolor{{localcolor}}{{rgb}}{{{}}}\nCOLOR'.format(self.color), result)
result = re.sub('COLOR', r'\\definecolor{{bordercolor}}{{rgb}}{{{}}}\n'.format(self.bordercolor), result)
result = re.sub('WIDTH', width, result)
print(result)
return latex_util.block(result)
class Block(klammer_base.Klammer_base):
def __init__(self, K):
super().__init__(K)
def tex(self):
# NOT latex_util.block(): a textblock is absolutely positioned and
# does not participate in the normal flow, so breaking the paragraph
# around it would move the surrounding text.
to_x, to_y = [float(e) for e in self.to.split()]
pt_x, pt_y = [float(e) for e in self.point.split()]
result = f"""
\\begin{{textblock}}{{{self.width}}}[{pt_x},{pt_y}]({to_x},{to_y})
\\vspace*{{-1\\parskip}}
{self.content.strip()}
\\end{{textblock}}
"""
return result
class Lines(klammer_base.Klammer_base):
def __init__(self, K):
super().__init__(K)
self.s = kutil.escape(self.s)
self.lines = self.s.split("\n")
def html(self):
result = ""
for line in self.lines:
result += line + "<br>\n"
return result
def tex(self):
return "\\\\\n".join(self.lines) + "\n"
def txt(self):
return self.lines