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

@@ -114,7 +114,7 @@ void missing_open(const Katom& k, bool error_exit)
std::stringstream ss {};
ss << "A klammer ends without a beginning: " << k;
if (error_exit) {
throw Parsing_error(ss.str(), k.m_loc, false);
throw Parsing_error(ss.str(), k.m_loc);
} else {
std::cout << " " << ss.str() << "\n";
}
@@ -134,7 +134,7 @@ void missing_close(const katom_list& bounds, bool error_exit)
ss << " " << k.m_loc << " " << k.m_src << "\n";
}
if (error_exit) {
throw Parsing_error(ss.str(), bounds[0].m_loc, false);
throw Parsing_error(ss.str(), bounds[0].m_loc);
} else {
std::cout << ss.str() << "\n";
}
@@ -148,7 +148,7 @@ void bad_close(const Katom& open, const Katom& close, bool error_exit)
<< " " << open.m_loc << " " << open << "\n"
<< " " << close.m_loc << " " << close;
if (error_exit) {
throw Parsing_error(ss.str(), open.m_loc, false);
throw Parsing_error(ss.str(), open.m_loc);
} else {
std::cout << ss.str() << "\n";
}
@@ -174,7 +174,7 @@ void check_named_katom_span(const Katom& begin, const Katom& end)
ss << " A named end katom does not match:\n"
<< " " << begin.m_loc << " " << begin << "\n"
<< " " << end.m_loc << " " << end;
throw Parsing_error(ss.str(), end.m_loc, false);
throw Parsing_error(ss.str(), end.m_loc);
}
}
}
@@ -370,6 +370,24 @@ void hide_special_katoms(katom_list& katoms)
definition_depth == 0 && code_depth == 0) {
k.m_text = hide_structural_characters(k.m_text);
}
// "^" before ANY punctuation character quotes it, not only the six
// Klammertext specials the katomizer knows: ^- is a literal hyphen
// (no dash transform), ^~ a literal tilde. The pair becomes the
// KTESC marker of the character here -- text-level, on writer-text
// katoms only, under the same span skips as the quoted specials
// above -- so code inside an @eval keeps its carets (grep '^-'
// reaches the shell intact) and ^'...'^ content (katom_t::literal,
// marked before this pass runs) stays exactly as typed. How the
// quoted character renders is the target's decision: the :escape
// and :resolve tables map its marker, and an unmapped marker
// decodes to the character itself. A katom this converts is no
// longer unparsed (the ^- warning would otherwise misfire).
if ((k.m_type == katom_t::word || k.m_type == katom_t::text) &&
definition_depth == 0 && code_depth == 0) {
if (hide_quoted_punctuation(k.m_text)) {
k.m_unparsed = false;
}
}
}
}
@@ -456,7 +474,7 @@ void check_bar_count(katom_iter begin, katom_iter end)
ss << "Incorrectly formatted @cond klammer. There should only be one or two bar characters:\n"
<< " @cond <predicate> | <result-if-true @\nor:\n"
<< " @cond <predicate> | <result-if-true> | <result-if-false> @";
throw Argument_error(ss.str(), begin->m_loc, false);
throw Argument_error(ss.str(), begin->m_loc);
}
}