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

@@ -257,7 +257,7 @@ void Argv::check_flags_and_options(const std::string& command, strings_t& words)
for (auto w : not_defined) {
ss << " " << w << "\n";
}
throw Argument_error(ss.str(), Locator(), false);
throw Argument_error(ss.str(), Locator::none());
}
}
@@ -288,7 +288,7 @@ void Argv::parse_flags(strings_t& words, string_map& named_args)
for (auto w : not_defined) {
ss << " " << w << "\n";
}
throw Argument_error(ss.str(), Locator(), false);
throw Argument_error(ss.str(), Locator::none());
}
*/
// std::cout << "Flags found: " << flag_args << "\n";
@@ -320,16 +320,29 @@ void Argv::parse_optional(strings_t& words, string_map& named_args)
"The option " + flag_name(opt) + " needs a value: " +
m_args[opt].m_syntax + ". Enter \"" +
file_basename(command_name) + "\" for the list of arguments.",
Locator(), false);
Locator::none());
}
std::string opt_arg = words[index] + " ";
index++;
std::regex opt_regex = m_args[opt].m_rgx;
// std::cout << "Regex match? " << std::regex_match(trim(opt_arg), opt_regex) << "\n";
while (index < words.size() && words[index][0] != '-'
// && std::regex_match(trim(opt_arg), opt_regex)
// Only a LIST-valued option may span several argv words
// (--klammersets a b c; --katoms type index). A single-valued
// option takes exactly ONE argv element -- argv boundaries are
// authoritative -- so a positional written after it is not
// swallowed into the value. The former unconditional run
// consumed everything up to the next dash-word: "-s 'text'
// doc.kt" folded doc.kt into the -s TEXT (and rendered its
// pathname), and "--klammersets none doc.kt" consumed the input
// filename, so ktext reported that none was given. -s must be
// usable in any argv position: its role with a file argument is
// to modify the interpretation of that file, and it is
// evaluated first regardless of where it is written. A list
// value stops at the "--" delimiter (it begins with '-'), which
// remains the escape for filenames after a list option.
bool list_valued = m_args[opt].m_rgx_symbol == "'list'"
|| m_args[opt].m_rgx_symbol == "'katom_display'";
while (list_valued && index < words.size() && words[index][0] != '-'
&& std::regex_match(trim(opt_arg + words[index]), opt_regex)
) {
@@ -370,7 +383,7 @@ void Argv::parse_positional(const std::string& command, //strings_t words,
}
std::stringstream ss {};
ss << "The argument " << q_(req) << " was not found in:\n " << command;
throw Argument_error(ss.str(), Locator(), false);
throw Argument_error(ss.str(), Locator::none());
}
named_args[req] = substring;
// Drop the whitespace that separated this positional from the next.
@@ -467,7 +480,7 @@ void Argv::check_flags(const string_map& arg_map, const std::string& command)
for (const std::string& undef : undefined) {
ss << " " << flag_name(undef);
}
throw Argument_error(ss.str(), Locator());
throw Argument_error(ss.str(), Locator::none());
}
}
@@ -508,7 +521,7 @@ void Argv::parse(int argc, char* argv[], bool full_parse)
usage(file_basename(argv[0]));
throw Argument_error(
"Incorrect value for option \"" + name + "\":\n" + m_args[name].m_desc + "\n",
Locator(), false);
Locator());
}
}
}
@@ -594,7 +607,8 @@ int Argv::as_verbosity(const std::string& name)
(void)K::log(2, name);
auto value = get(name);
if (!std::regex_match(value, std::regex(regex_symbols["'verbosity'"]))) {
throw Argument_error("Argument \"" + value + "\" is not a verbosity level");
throw Argument_error("Argument \"" + value + "\" is not a verbosity level",
Locator::none());
}
return std::stoi(value);
}