Escaping, table layout, and document fixes

Quoted Klammertext specials (^@ ^| ^# ^^ ^: ^*) and ^'...'^ regions now
survive re-processing (held as escape markers until final output);
:after_apply phase functions receive and return raw target text.

Tables: :hpos element position (center|left|right|<length>) replaces the
unimplemented :center/:indent; the ranged cell override is renamed
:justify; :column_width works in html (colgroup widths) and gains
'fill' -- the remaining width, capped at the column's widest entry, in
both targets; a table wider than the text column warns on the console;
table edges without an outer line set their text flush on the margins.

@document: no empty title bar for untitled documents; @vfill fills to
the bottom of the window in html (pure CSS); @vspace in plain text;
new @dot klammer; monospace email links.
This commit is contained in:
2026-07-25 21:16:21 +02:00
parent 4262fc6136
commit d61336b191
26 changed files with 650 additions and 75 deletions

View File

@@ -239,6 +239,7 @@ void Machine::process_katoms(
{
mark_literal_klammer_content(katoms);
if (literal) mark_literal_katoms(katoms);
hide_special_katoms(katoms);
if (nonascii) encode_nonascii_characters(katoms);
if (ignore) mark_ignored_katoms(katoms);
if (whitespace) process_whitespace_modifiers(katoms);
@@ -516,13 +517,22 @@ std::string Machine::run_phase_functions()
Target target = m_targets.get(m_state.value("K_target"), Locator());
if (!target.m_after_apply.empty()) {
(void)K::log(2, target);
Eval E(*this, Locator());
for (auto f : target.m_after_apply) {
// A mode-tagged spec (":cpp ...") names a function that receives
// the Machine itself; a bare Python function is called with the
// result text. The Eval is constructed per phase so a chained
// phase sees its predecessor's result in K_result.
Eval E(*this, Locator());
if (!f.empty() && f[0] != ':') {
f += "(K_result)";
}
f = "@eval " + f + " @";
auto katoms = katomize(line_split(f), "phase");
katom_list eval_katoms = E.eval(katoms.begin(), katoms.end() - 2);
// msg() << "eval_katoms: " << eval_katoms << "\n";
m_result = to_string(eval_katoms.begin(), eval_katoms.end());
// A phase function's input and output are final target text, not
// Klammertext: take the raw result string. Re-reading it as
// Klammertext (Eval::eval) would misparse target characters --
// e.g. a "@" from a quoted ^@ in justified txt output.
m_result = E.eval_command(katoms.begin(), katoms.end() - 2);
}
}
return m_result;