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:
@@ -16,9 +16,9 @@ bool strbool(const std::string& s, const Locator& loc)
|
||||
std::vector<std::string> values = {"false", "False", "0", "true", "True", "1"};
|
||||
if (is_not_in(s, values)) {
|
||||
std::stringstream ss {};
|
||||
ss << "The value \"" << s << "\" is not a Boolean values. Possible values are:\n"
|
||||
ss << "The value \"" << s << "\" is not a Boolean value. Possible values are:\n "
|
||||
<< join(values, ", ");
|
||||
throw Argument_error(ss.str(), loc, false);
|
||||
throw Argument_error(ss.str(), loc);
|
||||
}
|
||||
bool result = (find(values.begin(), values.end(), s) - values.begin()) > 2;
|
||||
return result;
|
||||
@@ -51,10 +51,15 @@ Document_class::Document_class(Machine& machine) : Klammer_base(machine)
|
||||
// spaces, ~ expansion (resolve_filename_list in mac/file.cpp); the
|
||||
// existence checks resolve relative names against the input directory,
|
||||
// as parse_input_filename() will.
|
||||
m_files = resolve_filename_list(get("files"), get("K_input_dir"));
|
||||
// Filename-bearing values arrive ESCAPED for the target (the state
|
||||
// stores escaped values so they flow correctly into output); a filename
|
||||
// is programmatic use, so decode the markers first -- the C++ mirror of
|
||||
// the Python-side unescape_ktesc() rule. Found 2026-08-22: under tex,
|
||||
// ":files my_chapter" searched for "myKTESC005fKTESCchapter".
|
||||
m_files = resolve_filename_list(ktesc_resolve(get("files")), get("K_input_dir"));
|
||||
|
||||
m_css_text = get("css_text");
|
||||
m_css_filenames = resolve_filename_list(get("css_files"), get("K_input_dir"));
|
||||
m_css_filenames = resolve_filename_list(ktesc_resolve(get("css_files")), get("K_input_dir"));
|
||||
m_include_sks_css = strbool(get("include_sks_css"), loc);
|
||||
frame_background_color = get("frame_background_color");
|
||||
frame_text_color = get("frame_text_color");
|
||||
@@ -62,7 +67,7 @@ Document_class::Document_class(Machine& machine) : Klammer_base(machine)
|
||||
nav_text_color = get("nav_text_color");
|
||||
|
||||
js_text = get("js_text");
|
||||
m_js_filenames = resolve_filename_list(get("js_files"), get("K_input_dir"));
|
||||
m_js_filenames = resolve_filename_list(ktesc_resolve(get("js_files")), get("K_input_dir"));
|
||||
m_include_sks_js = strbool(get("include_sks_js"), loc);
|
||||
|
||||
// font_dirs = word_split(get("font_dirs"));
|
||||
@@ -138,33 +143,49 @@ void Document_class::save_string_input_as_file()
|
||||
|
||||
fs::path parse_input_filename(const std::string& s, const std::string& input_dir)
|
||||
{
|
||||
// The two-class rule (2026-08-22), replacing a three-stage search whose
|
||||
// second stage could quietly shadow a file beside the document:
|
||||
//
|
||||
// * a BARE WORD -- no directory separator, no extension -- is the kt/
|
||||
// SHORTCUT: ":files X" MEANS kt/X.kt in the root file's directory,
|
||||
// and nothing else. Missing is an immediate error whose message
|
||||
// teaches the convention, not a fallback. The kt/ directory is the
|
||||
// conventional home for a document's input files, and putting the
|
||||
// meaning entirely in the name lets several root documents share it.
|
||||
//
|
||||
// * anything else is a real PATHNAME, absolute or resolved against the
|
||||
// input file's directory (K_input_dir), so a document renders
|
||||
// identically wherever ktext is run from.
|
||||
//
|
||||
// Which file a name landed on is a DERIVED value, so "-v 1" reports it.
|
||||
fs::path p(s);
|
||||
bool bare = s.find('/') == std::string::npos && p.extension().empty();
|
||||
if (bare) {
|
||||
fs::path in_kt = fs::path(input_dir) / "kt" / (s + ".kt");
|
||||
if (!file_exists(in_kt.string())) {
|
||||
throw Argument_error(
|
||||
"The \":files\" name \"" + s + "\" is a bare word, which by "
|
||||
"convention means the file kt/" + s + ".kt in the root "
|
||||
"document's directory:\n"
|
||||
" " + in_kt.string() + "\n"
|
||||
"That file does not exist. Create it there, or write a real "
|
||||
"pathname (a name with a directory or the \".kt\" extension) "
|
||||
"to use a file elsewhere.",
|
||||
Locator::none());
|
||||
}
|
||||
// The resolved path itself shows kt/ -- no label needed.
|
||||
(void)K::log(1, "Input file \"" + s + "\": " + in_kt.string());
|
||||
return in_kt;
|
||||
}
|
||||
if (p.extension() != ".kt") {
|
||||
p += ".kt";
|
||||
}
|
||||
if (p.is_absolute()) {
|
||||
return p;
|
||||
}
|
||||
// A relative :files name resolves against the input file's directory
|
||||
// (K_input_dir), so a document renders identically wherever ktext is
|
||||
// run from; then the legacy kt/ subdirectory; a name found in neither
|
||||
// is returned as given (cwd-relative) and errors downstream.
|
||||
// Which of the three a name landed on is a DERIVED value -- the ".kt" may
|
||||
// have been supplied, and the directory certainly was -- so "-v 1" reports
|
||||
// it. A ":files chapter1" that quietly found kt/chapter1.kt rather than
|
||||
// the file beside the document is exactly what the author cannot see.
|
||||
fs::path in_input_dir = fs::path(input_dir) / p;
|
||||
if (file_exists(in_input_dir.string())) {
|
||||
(void)K::log(1, "Input file \"" + s + "\": " + in_input_dir.string());
|
||||
return in_input_dir;
|
||||
}
|
||||
fs::path in_kt_dir = fs::path(input_dir) / "kt" / p;
|
||||
if (file_exists(in_kt_dir.string())) {
|
||||
(void)K::log(1, "Input file \"" + s + "\": " + in_kt_dir.string()
|
||||
+ " (found in the kt/ subdirectory)");
|
||||
return in_kt_dir;
|
||||
}
|
||||
return p;
|
||||
(void)K::log(1, "Input file \"" + s + "\": " + in_input_dir.string());
|
||||
return in_input_dir;
|
||||
}
|
||||
|
||||
void Document_class::write(const std::string& filename, const std::string& contents)
|
||||
|
||||
Reference in New Issue
Block a user