Typed arguments, calculated tables, spans, closed-world fonts, top-level fnt/ and env/

Sync with klammertext-dev through b90b0e09:

- Argument types end to end: :python_cast values are applied (Python
  @eval receives real bools/numbers/lists), argument values are
  validated against their argtype patterns with the argtype's
  description as the error message, argtypes can declare :default
  (overridable per declaration), and parameterized type families are
  supported: rest(N) casts a rest argument to an N-dimensional list
  (bar-count = dimension).
- Unified indexed_range syntax (selector with parenthesized subsets,
  composable mnemonic names) for table lines and spans.
- Table klammer: caption fonts fixed in both targets, :column_width /
  :leading / :colsep wired, :colspan and :rowspan render (HTML
  attributes; \multicolumn / \multirow), calculated cell values (:calc)
  with prefix operators, display-precision semantics, :calc_format and
  :decimal period|comma.
- Fonts: closed-world resolution on the Klammertext font store
  (infrastructure in mac/font_store; no Google Fonts links or fetch).
  Default fonts live in the top-level fnt/; additional fonts install
  into KLAMMERTEXT_FONTS directories via kdesc --font (list, samples,
  preview, install — classification by font metadata).  CSS font family
  names are quoted (digit-initial families were silently lost).
- Environment files moved from mac/env/ to the top-level env/; shell
  profiles source env/runtime.env.  Dead per-host variants removed.
- Container: fnt/ ships in the image; curl removed (no network use).
This commit is contained in:
2026-07-22 18:17:43 +02:00
parent 6b75aa0c54
commit 8a2699a253
100 changed files with 1726 additions and 1152 deletions

View File

@@ -13,7 +13,7 @@
Parameter_set& Argtype_set::parameters()
{
static Parameter_set instance("name | desc :pattern .* :python_cast str");
static Parameter_set instance("name | desc :pattern .* :python_cast str :default");
return instance;
}
@@ -22,8 +22,11 @@ Argtype_set::Argtype_set()
(void)(void)K::log(2);
Locator loc = current_locator();
for (auto [name, desc, pattern, python_cast, python_format] : base_argtypes) {
add(name, desc, pattern, python_cast, python_format, loc);
add(name, desc, pattern, "", python_cast, python_format, loc);
}
// rest is a parameterized type (rest(N)); an unparameterized use is
// one-dimensional.
m_types["rest"].m_parameter = "1";
}
std::string Argtype_set::replace_symbols(const std::string& pattern, const Locator& loc)
@@ -58,8 +61,8 @@ void Argtype_set::check_for_existing_definition(
}
}
void Argtype_set::add(const std::string& name, const std::string& desc,
const std::string& pattern,
void Argtype_set::add(const std::string& name, const std::string& desc,
const std::string& pattern, const std::string& default_value,
const std::string& python_cast, modify_string_f python_format,
const Locator& loc)
{
@@ -68,17 +71,35 @@ void Argtype_set::add(const std::string& name, const std::string& desc,
std::string expanded_pattern = replace_symbols(pattern, loc);
m_name_size = std::max(m_name_size, name.size()); // For display
m_pattern_size = std::max(m_pattern_size, expanded_pattern.size());
m_types[name] = Argtype(name, desc, pattern, expanded_pattern, python_cast, python_format, loc);
try {
m_types[name] = Argtype(name, desc, pattern, expanded_pattern,
default_value, python_cast, python_format, loc);
} catch (const std::regex_error& e) {
std::stringstream ss {};
ss << "The pattern for argument type \"" << name
<< "\" is not a valid regular expression (" << e.what() << "):\n"
<< " " << pattern << "\n";
if (pattern != expanded_pattern) {
ss << "expanded to:\n " << expanded_pattern << "\n";
}
throw Definition_error(ss.str(), loc, false);
}
if (!default_value.empty() &&
!std::regex_match(default_value, m_types[name].m_regex)) {
std::stringstream ss {};
ss << "The default value \"" << default_value << "\" for argument type \""
<< name << "\" does not match its own pattern:\n"
<< " " << pattern << "\n";
throw Definition_error(ss.str(), loc, false);
}
m_names.push_back(name);
}
void Argtype_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms)
{
(void)K::log(3);
//Argument_set parameters("name | desc :pattern .* :python_cast str");
auto [positional, optional, rest] =
argument_split(begin + 1, end); //, Argtype_set::parameters.m_positional.size());
argument_split(begin + 1, end - 1); //, Argtype_set::parameters.m_positional.size());
check_for_existing_definition(positional[0][0].m_text, begin->m_loc);
@@ -86,11 +107,8 @@ void Argtype_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::it
// std::for_each(begin, end+1, [](Katom& k) { k.m_type = katom_t::replaced; });
modify_string_f pyformat {};
std::string pycast {};
add(values["name"], values["desc"], values["pattern"],
pycast, pyformat,
add(values["name"], values["desc"], values["pattern"], values["default"],
values["python_cast"], modify_string_f{},
begin->m_loc);
modify_type(katom_t::replaced, begin, end);