The ansi target, txt table styles, kdesc reference from ref/, typeface and table-width fixes (from dev fcec5e2e77ac)

Since the previous release: Machine::read_string() (the fs::path/std::string
overload pair split); kdesc -c and -u rendered from the ref/ reflection
klammerset; a fit column's tex width measured in TeX over every entry;
@typeface resolving to the family its css declares (a store directory name
now works in html) and hieroglyphs in @unicode_examples set in their
typeface; the ansi target -- plain text with the type styles a terminal can
show, identical to txt once the escape sequences are stripped -- with the
txt @table carrying :header_style, :style and :hline; @block anchoring,
@table spacing and the Image_quality state variable; and the rewritten
doc/klammertext_for_llm.md.
This commit is contained in:
ack committed 2026-09-12 18:11:48 +02:00
1 parent 760fda5470
commit 9b0d0d7897
34 files changed
+895 -394

No files matched your search

+1 -172
View File
@@ -172,7 +172,7 @@ std::string process_pinyin(std::string s)
return result;
}
std::string process_unicode_codepoint(std::string s, const Locator& loc = Locator::none())
std::string process_unicode_codepoint(std::string s, const Locator& loc)
{
(void)K::log(4);
std::string result {s};
@@ -267,174 +267,3 @@ std::string encode(const std::string& s, const Locator& loc)
return result;
}
// Decode
// Display
void write_kt_example_file(std::stringstream& kt, std::string kt_filename)
{
kt << "|| @line@\n";
kt << "@\n";
std::cout << "Writing " << kt_filename << "...";
std::ofstream out(kt_filename);
out << kt.str();
out.close();
std::cout << "done\n";
}
/*
void diacritics_examples(const std::string& kt_filename)
{
if (diacritics.size() != diacritic_symbols_order.size()) {
//throw Internal_error("Mismatch between diacritics order list and their definitions");
std::cout << "Mismatch error\n";
}
std::stringstream kt {};
bool write_kt_file = kt_filename.size() != 0;
if (write_kt_file)
kt << "@table :caption Diacritics (with typical base characters) |\n"
<< " @i-Displayed | @i-Written | @i-Name\n";
else
std::cout << boldblack
<< "\nDiacritics (with typical base characters)\n\n" << black;
std::string line_sep = "|| @line@ ";
for (char symbol : diacritic_symbols_order) {
std::string sym { symbol };
auto [code, name] = diacritics[sym];
std::string letter = diacritic_example_letter[sym];
std::string written = "^" + letter + sym;
if (sym == "~") {
written = "^" + letter + "=7e=";
}
if (write_kt_file) {
std::string display = "^" + letter + sym;
kt << line_sep << display << " | @t ^" << written << " @ | " << name << "\n";
line_sep = "|| ";
}
else {
std::cout << " " << letter << unicode_hex_to_char(code)
<< " " << "^" << letter << symbol << " " << name << "\n";
}
}
if (write_kt_file)
write_kt_example_file(kt, kt_filename);
}
*/
/*
void extended_latin_examples(const std::string& kt_filename)
{
std::stringstream kt {};
bool write_kt_file = kt_filename.size() != 0;
std::string title = "Extended Latin characters and ligatures";
if (write_kt_file)
kt << "@table :caption " << title << " |\n"
<< " @i-Displayed | @i-Written | @i-Name\n";
else
std::cout << "\n" << boldblack << title << black << "\n\n";
std::string line_sep = "|| @line@ ";
for (const std::string& symbol : extended_latin_symbols) {
auto [code, name] = extended_latin[symbol];
if (write_kt_file) {
std::string coded = "^" + symbol + "^";
std::string file_literal = "^^ #- " + symbol + " #- ^^";
kt << line_sep << coded << " | @t " << file_literal << " @ | " << name << "\n";
line_sep = "|| ";
}
else {
std::string screen_literal = "^" + symbol + "^";
std::cout << " " << unicode_hex_to_char(code)
<< " " << std::setw(4) << std::left << screen_literal << " " << name << "\n";
}
}
if (write_kt_file)
write_kt_example_file(kt, kt_filename);
}
*/
void pinyin_examples(const std::string& kt_filename)
{
std::stringstream kt {};
bool write_kt_file = kt_filename.size() != 0;
if (write_kt_file)
kt << "@table :caption Mandarin pinyin tones (using vowel ``a'') |\n"
<< " @i-Displayed | @i-Written | @i-Name\n";
else
std::cout << boldblack
<< "\nMandarin pinyin tones (using vowel \"a\")\n\n" << black;
std::string line_sep = "|| @line@ ";
for (auto [symbol, codename] : pinyin_tones) {
auto [code, name] = codename;
// std::string hat_code = "^a" + code;
std::string literal = "^a" + symbol;
if (write_kt_file) {
kt << line_sep << literal << " | @t ^" << literal << " @ | " << name << "\n";
line_sep = "|| ";
} else
std::cout << " a" << unicode_hex_to_char(code)
<< " "<< std::setw(4) << std::left << literal << " " << name << "\n";
}
if (write_kt_file)
write_kt_example_file(kt, kt_filename);
}
/*
Outside my window
crows build a nest in a tree...
slowly... carefully.
*/
void unicode_examples(const std::string& kt_filename)
{
std::stringstream kt {};
bool write_kt_file = kt_filename.size() != 0;
std::cout << boldblack << "\nIncluding Unicode in Klammertext files\n\n" << black
<< "To specify a wide variety of different letter forms, the Unicode Standard\n"
<< "defines a large set of \"code points\" organized by groups. To include a\n"
<< "Unicode character in Klammertext, you surround its hexadecimal number with\n"
<< "the \"^\" character. For example, the Cyrillic captial letter \"I\" is \"И\",\n"
<< "included in Klammertext as ^0418^.\n\n"
<< "To search for Unicode characters by their description, see:\n"
<< " https://www.fileformat.info/info/unicode/char/search.htm\n";
std::cout << "\n⟐ Examples of Chinese characters\n\n"
<< " Pinyin\n";
for (auto chr : dao) {
std::string code = "^" + chr[1] + "^";
std::cout << " " << process_unicode_codepoint(code) << " "
<< code << " "
<< chr[0] << "\n";
}
std::cout << "\n⟐ Examples of Egyptian hieroglyphs\n\n";
std::cout << std::setw(16) << " " << "Sound Gardiner\n";
for (auto glyph : ptolemy) {
std::cout << " " << std::setw(4) << process_unicode_codepoint("^" + glyph[2] + "^") << " "
<< "^" + glyph[2] + "^ "
<< std::setw(4)
<< glyph[1] << " "
<< std::setw(4)
<< glyph[0] << "\n";
}
std::cout << "\nSee: https://en.wikipedia.org/wiki/List_of_Egyptian_hieroglyphs\n"
<< "The Unicode codepoint in the second column of the \"List of hieroglyphs\"\n"
<< "table is the number in the ^...^ code used by Klammertext.\n\n";
}
void show_special_characters()
{
std::cout << std::setfill(' ');
// diacritics_examples();
// extended_latin_examples();
pinyin_examples();
}
+3 -9
View File
@@ -59,7 +59,7 @@ inline
std::map<std::string, std::pair<std::string, std::string>> diacritics {
{"`", {"0300", "grave accent"}},
{"'", {"0301", "acute accent"}},
{"h", {"0302", "circumflex"}},
{"h", {"0302", "circumflex (hat)"}},
{"~", {"0303", "tilde"}},
{"-", {"0304", "macron"}},
{"\"", {"0308", "diaresis"}},
@@ -138,6 +138,8 @@ const std::string italic_on() { return is_tty() ? "\033[3m" : ""; }
inline
const std::string italic_off() { return is_tty() ? "\033[0m" : ""; }
std::string process_unicode_codepoint(std::string s, const Locator& loc = Locator::none());
std::string encode(const std::string& s, const Locator& loc);
// UTF-8 encoding of one code point (to U+10FFFF; surrogates and values
@@ -154,11 +156,3 @@ std::string utf8char(int cp);
// "Invalid Unicode" text is no longer reachable from input).
bool valid_codepoint(int cp);
std::string invalid_codepoint_reason(int cp);
// void diacritics_examples(const std::string& kt_filename = "");
// void extended_latin_examples(const std::string& kt_filename = "");
void pinyin_examples(const std::string& kt_filename = "");
void unicode_examples(const std::string& kt_filename = "");
void show_special_characters();
+1 -1
View File
@@ -336,7 +336,7 @@ katom_list Eval::eval(katom_iter begin, katom_iter end)
Machine M = m_machine;
M.m_warn_unparsed = false; // Result text is machine-generated (see machine.h)
size_t before = M.m_katoms.size();
M.read(eval_result);
M.read_string(eval_result);
// If the @eval produced more Klammertext -- the read-back result still
// holds klammers to reduce (a "generator", e.g. a Python klammer returning
// a @table call with data) -- then its text is writer content: escape it
+9
View File
@@ -89,6 +89,15 @@ static void classify_from_css(Resolved_font& font, std::string css_path)
{
// Parse the @font-face blocks in the CSS to determine variant → filename mapping
std::string css = string_from_file(css_path);
// The family name is what the css DECLARES, not what the caller wrote:
// a typeface may be asked for by its directory name
// ("noto-sans-egyptian-hieroglyphs"), and a font-family value in
// generated html must match the @font-face or the browser substitutes
// silently (until 2026-09-12 the request was echoed back).
static const std::regex family_rgx(R"(font-family:\s*'([^']+)')");
std::smatch match;
if (std::regex_search(css, match, family_rgx))
font.family_name = match[1];
std::regex face_rgx(
R"(@font-face\s*\{[^}]*font-style:\s*(\w+);[^}]*font-weight:\s*(\w+);[^}]*url\('([^']+\.ttf)'\)[^}]*\})",
std::regex::multiline);
+12 -12
View File
@@ -482,25 +482,25 @@ void Machine::read(const fs::path& pathname)
// :cpp libraries live next to the file that uses them).
m_state.add_search_dir(fs::absolute(pathname).parent_path().string());
m_state.open_frame("Machine state: " + pathname.string());
std::string text = m_state.subst(trim_right(string_from_file(pathname)));
katom_list katoms = process(text, pathname);
m_katoms.insert(m_katoms.end(), katoms.begin(), katoms.end());
extract_machine_definitions();
extract_klammer_definitions();
input(string_from_file(pathname), pathname.string());
m_sources.push_back(pathname);
}
void Machine::read(const std::string& s)
void Machine::read_string(const std::string& text)
{
(void)K::log(3, s);
m_state.open_frame("Machine state: " + s);
std::string text = m_state.subst(trim_right(s));
katom_list katoms = process(text, command_pathname);
(void)K::log(3, text);
m_state.open_frame("Machine state: " + text);
input(text, command_pathname);
m_sources.push_back(text);
}
void Machine::input(const std::string& text, const std::string& source)
{
katom_list katoms = process(m_state.subst(trim_right(text)), source);
m_katoms.insert(m_katoms.end(), katoms.begin(), katoms.end());
extract_machine_definitions();
extract_klammer_definitions();
m_sources.push_back(s);
}
}
// Read
+9 -2
View File
@@ -69,8 +69,15 @@ public:
bool nonascii=true, bool literal=true, bool ignore=true, bool whitespace=true,
bool klammers=true, bool eval=true, bool cond=true, bool read=true);
void read(const fs::path& pathname);
void read(const std::string& s);
// Two ways to give the Machine its input. They are named, not
// overloaded: fs::path and std::string convert into each other freely
// enough that a string literal is ambiguous between them and a
// std::string holding a filename silently selects the text reading.
void read(const fs::path& pathname); // the file's contents
void read_string(const std::string& text); // the string itself
// What both do once they have the text: substitute, katomize, extract
// definitions. `source` names where the text came from in messages.
void input(const std::string& text, const std::string& source);
void expand_read_katoms(
std::vector<Katom>& katoms, std::string source_filename,