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

@@ -20,7 +20,7 @@ parse_name(const Target_registry& targets, const Katom& name_katom)
if (!std::regex_match(name_with_target, match, Klammer::name_re)) {
throw Parsing_error(
"The klammer name \"" + name_with_target + "\" is not correctly defined. "
"The klammer name \"" + name_with_target + "\" is not correctly defined.\n\n"
"The form is \"<klammer-name>\" for general klammers or \"<klammer-name>.<target-name>\" "
"for a specialized target. Several targets that share one body are written as a "
"comma-separated list: \"<klammer-name>.<target-name>,<target-name>\". The klammer "
@@ -44,7 +44,7 @@ parse_name(const Target_registry& targets, const Katom& name_katom)
if (!targets.has(target_name)) {
throw Target_error(
"The target \"" + target_name + "\" in klammer definition \"" + name_with_target + "\" "
"is not defined. Enter \"kdesc -t\" to see the targets defined by the Standard Klammer Set.",
"is not defined.\n\nEnter \"kdesc -t\" to see the targets defined by the Standard Klammer Set.",
name_katom.m_loc);
}
if (is_in(target_name, seen)) {
@@ -105,7 +105,7 @@ parse_definition_katoms(
" @@<name>[.<target>] :: <body> @@ instance (uses .k parameters)\n"
" @@<name>[.<target>] ::: <body> @@ override existing definition\n"
" @@<name>[.<target>] <parameters> :::: <body> @@ default (can be overridden)",
begin->m_loc, false);
begin->m_loc);
}
katom_list parameter_katoms(begin, deftype);
@@ -274,7 +274,7 @@ void Klammer::disallow_instances() //Klammer::components declaration)
<< plural("instance", icount) << " (defined by \"::\"), but "
<< "no declarations (defined by a \".k\" target)";
throw Definition_error(
error_list(ss.str(), instances), instances[0].loc, false);
error_list(ss.str(), instances), instances[0].loc);
}
}
@@ -295,7 +295,7 @@ bool Klammer::copy_to_instances(const Target_registry& targets)
<< plural("instance", icount) << " (defined by \"::\"), but "
<< dcount << " "<< plural("definition", dcount) << " (defined by \":\")";
throw Definition_error(
error_list(ss.str(), definitions), definitions[0].loc, false);
error_list(ss.str(), definitions), definitions[0].loc);
} else {
copy_components(definitions[0].parameters, m_defs, targets);
return true;
@@ -336,7 +336,7 @@ void Klammer::check_for_multiple_general_klammers()
error_list(
"There is more than one general klammer (a klammer in which no target is defined)",
general_klammers),
general_klammers[0].loc, false);
general_klammers[0].loc);
}
}
@@ -362,7 +362,7 @@ void Klammer::check_for_declaration_and_definitions()
".\nWrite \"::\" instead of \":\" so the definition takes its parameters "
"from the declaration",
definitions),
declares[0].loc, false);
declares[0].loc);
}
}
}
@@ -384,7 +384,7 @@ void Klammer::copy_general_klammer_to_undefined(const Target_registry& targets)
throw Definition_error(
error_list("The general parameters are different than the defined parameters",
general_klammers),
m_parameters.m_katoms[0].m_loc, false);
m_parameters.m_katoms[0].m_loc);
}
}
const auto& [target, deftype, parameters, body, varmap, loc] = general_klammers[0];
@@ -470,19 +470,19 @@ void Klammer::no_declarations(const Target_registry& targets)
// definitions by hand to find which one drifted.
std::stringstream ss {};
ss << "The parameters of klammer \"" << m_name
<< "\" are not the same for every target,\n"
<< "\" are not the same for every target, "
"and there is no declaration (.k) target to define them once:\n";
for (const auto& def : m_defs) {
if (std::ranges::find(target_names, def.target) == target_names.end())
continue;
std::string target = def.target;
target.resize(std::max(target.size(), size_t(6)), ' ');
ss << " " << target << " " << parameter_signature(def.parameters)
<< "\n " << def.loc.desc() << "\n";
target.resize(std::max(target.size(), size_t(4)), ' ');
ss << " Target: " << target << " Parameters: " << parameter_signature(def.parameters)
<< "\n " << def.loc.desc() << "\n";
}
ss << "Use a .k target to declare the parameters and describe the klammer,\n"
"and \"::\" with no parameters for each target's definition.";
throw Definition_error(ss.str(), m_defs[0].loc, false);
throw Definition_error(ss.str(), m_defs[0].loc);
} else {
// std::cout << " All equal\n";
copy_components(m_defs[0].parameters, m_defs, targets);
@@ -506,7 +506,7 @@ void Klammer::many_declarations(const std::vector<Klammer::components>& declares
// std::cout << boldblack << "Many declarations\n" << black;
throw Definition_error(
error_list("More than one declaration (.k) klammer", declares),
declares[0].loc, false);
declares[0].loc);
}