Files
klammertext/mac/ktype.cpp
Andy Kopra 2ba7ceee7a Initial commit: Klammertext source distribution
Curated source subset assembled by klammertext-dev's doc/make_dist.sh: the Klammermachine (mac), the Standard Klammer Set (sks), the commands (com), editor plugins and install guides (doc), a test subset (tst), and lib/bin placeholders. Builds with 'make -C com'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 19:32:38 +02:00

208 lines
6.2 KiB
C++

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <utility>
#include "locator.h"
#include "ktype.h"
#include "log.h"
#include "file.h"
#include "show.h"
#include "util.h"
/*
bool is_error(katom_t t)
{
return
t == katom_t::undefined ||
t == katom_t::no_matching_end ||
t == katom_t::no_matching_begin ||
t == katom_t::karg_error ||
t == katom_t::klammer_definition_type_error ||
t == katom_t::eval_error;
}
*/
bool is_active(katom_t type)
{
return type != katom_t::ignored
&& type != katom_t::replaced;
}
bool is_printable(katom_t type)
{
return printable_katom_types.find(type) != printable_katom_types.end();
}
bool is_deftype(katom_t type)
{
return
type == katom_t::klammer_definition ||
type == katom_t::klammer_instance ||
type == katom_t::klammer_override ||
type == katom_t::klammer_default;
}
std::string pattern_display(Ktype t)
{
std::string pat{};
if (t.m_type == katom_t::space) {
pat = "<space>";
} else if (t.m_type == katom_t::newline) {
pat = "\\n";
} else if (t.m_type == katom_t::ws_space) {
pat = "#+ or #+<number>";
} else if (t.m_type == katom_t::ws_newline) {
pat = "#/ or #/<number>";
} else if (t.m_type == katom_t::special) {
pat = "^@, ^|, ^#, ^:, or ^^";
} else if (t.m_type == katom_t::apply_end) {
pat = "@ or <name>@";
} else if (t.m_type == katom_t::define_end) {
pat = "@@ or <name>@@";
} else if (t.m_type == katom_t::machine_end) {
pat = "@@@ or <name>@@@";
} else if (t.m_type == katom_t::ws_added) {
pat = "<space> or \\n";
} else if (t.m_type == katom_t::word) {
pat = "<only-letters>";
} else if (t.m_type == katom_t::text) {
pat = "<no-special-chars>";
} else if (t.m_type == katom_t::nonascii) {
pat = "^<code> or ^<code>^";
} else {
pat = t.m_pattern;
pat = string_replace(pat, definition_name, "<name>");
pat = string_replace(pat, "\\", "");
}
return pat;
}
std::string regex_display(Ktype t)
{
std::string rgx{};
if (t.m_type == katom_t::space) {
rgx = "<space>";
} else if (t.m_type == katom_t::newline) {
rgx = "\\n";
} else {
rgx = t.m_pattern;
}
return rgx;
}
Ktype find_katom_type(katom_t type)
{
for (auto t : katom_types) {
if (t.m_type == type) {
return t;
}
}
throw Internal_error("Unknown katom_t: " + std::to_string((int)type));
}
void describe_katoms(bool show_regex)
{
size_t name_w = 0;
size_t pattern_w = 0;
size_t regex_w = 0;
size_t description_w = 0;
std::stringstream ss {};
ss << R"(
A "katom" is an individual element in the Klammertext input text.
Each katom has a type, listed below. You can see how Klammertext
divides up text into katoms with the "kdiag" command.)" << "\n\n";
if (show_regex) {
ss << R"(The "Regex" column is the argument to the std::regex C++ function.)";
} else {
ss << R"(In the katom patterns, "<name>" is a word that begins with a letter
and only contains letters, numbers, or the underscore (_) or period (.) characters. )";
}
ss << "A <number> is an integer greater than or equal to 1. "
"A <code> is one of the non-ASCII codes that are displayed by the command "
"\"kdesc -c\".";
for (auto t : katom_types) {
name_w = std::max(name_w, t.m_name.size());
pattern_w = std::max(pattern_w, pattern_display(t).size());
regex_w = std::max(regex_w, regex_display(t).size());
description_w = std::max(description_w, t.m_description.size());
}
pattern_w++;
regex_w++;
std::cout << justify(ss.str()) << "\n\n"
<< std::setfill(' ') << boldblack << std::right << std::setw(6) << "Index"
<< std::left
<< std::setw(name_w) << " Name" << " ";
if (show_regex) {
std::cout << std::setw(regex_w) << " Regex" << " ";
} else {
std::cout << std::setw(pattern_w) << " Pattern" << " ";
}
std::cout << std::setw(description_w) << "Description"
<< "\n" << black;
for (auto typ : katom_type_display_order) {
auto t = find_katom_type(typ);
std::cout << " " << std::right << std::setw(3)
<< static_cast<int>(t.m_type) << " "
<< std::left
<< std::setw(name_w) << t.m_name << " ";
if (show_regex) {
std::cout << std::setw(regex_w) << regex_display(t) << " ";
} else {
std::cout << std::setw(pattern_w) << pattern_display(t) << " ";
}
std::cout << std::setw(description_w) << t.m_description << "\n";
}
std::cout << "\n";
}
void describe_rewrite_patterns()
{
if (verbose_level > 0) {
std::string desc_text = "doc/katom_patterns.desc";
std::cout << "\n"
<< justify(string_from_file(klammertext_filename(desc_text)))
<< "\n\n";
}
size_t width1 = 0;
size_t width2 = 0;
for (auto [desc, pattern, replace] : katom_rewrite_rules) {
width1 = std::max(width1, desc.size());
width2 = std::max(width2, pattern.m_pattern.size());
}
width1 += 2;
width2 += 2;
std::cout << boldblack << std::setfill(' ')
<< std::setw(width1) << std::left << " Description"
<< std::setw(width2) << std::left << " Pattern"
<< " Replacement" << black << "\n";
for (auto [desc, pattern, replace] : katom_rewrite_rules) {
desc[0] = toupper(desc[0]);
std::cout << " "
<< std::left
<< std::setw(width1) << desc
<< std::setw(width2) << pattern.m_pattern
<< replace
<< "\n";
}
if (verbose_level > 0) {
std::string notes_text = "doc/katom_patterns.notes";
std::cout << "\n\n"
<< justify(string_from_file(klammertext_filename(notes_text)))
<< "\n\n";
}
}
std::string type_to_name(katom_t type)
{
auto var = std::find_if(katom_types.begin(), katom_types.end(),
[&] (Ktype t) { return t.m_type == type; });
return var->m_name;
}