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

@@ -254,25 +254,6 @@ namespace html {
return result;
}
elements_t google_font_elements(strings_t fontnames)
{
elements_t result {};
if (fontnames.size() > 0) {
result.push_back(elt("link")
.attr("rel", "preconnect")
.attr("href", "https://fonts.googleapis.com"));
result.push_back(elt("link")
.attr("rel", "preconnect")
.attr("href", "https://fonts.gstatic.com"));
}
for (auto name : fontnames)
result.push_back(
elt("link")
.attr("href", "https://fonts.googleapis.com/css2?family=" + name + "&display=swap")
.attr("rel", "stylesheet"));
return result;
}
elements_t javascript(std::string output_dir, strings_t js_filenames)
{
//elements_t result { jquery_elements() };
@@ -298,15 +279,12 @@ namespace html {
HTML head(std::string title,
std::string css,
strings_t css_filenames,
strings_t local_fonts, strings_t google_fonts)
strings_t local_fonts)
{
elements_t elts = meta_elements();
// msg() << "ELTS sks: " << elts << "\n";
for (auto e : local_font_elements(local_fonts))
elts.push_back(e);
for (auto e : google_font_elements(google_fonts))
elts.push_back(e);
//elts += google_font_prolog();
//std::string css_dir = output_dir + "/css/";
// No; a single file at the top level...?
@@ -471,55 +449,6 @@ namespace html {
return result;
}
void install_local_fonts(strings_t font_dirs, strings_t names, std::string output_dir)
{
std::string output_font_dir = output_dir + "/fonts";
//std::cout << "Font directory for website: " << output_font_dir << "\n";
if (!file_exists(output_font_dir)) {
fs::create_directory(output_font_dir);
//std::cout << " Font directory created: " << output_font_dir << "\n";
}
for (auto name : names) {
//std::cout << "Font search for " << name << ": " << klammertext_dir() << "/sks/font/fonts/\n";
std::string src_font_dir = klammertext_dir() + "/sks/font/fonts/" + name;
if (!file_exists(src_font_dir)) {
bool found = false;
for (std::string font_dir : font_dirs) {
src_font_dir = font_dir + "/" + name;
//std::cout << "Font search for " << name << ": " << font_dir << "/\n";
if (file_exists(src_font_dir)) {
found = true;
break;
}
}
if (!found) {
throw Argument_error(
"Local font directory \"" + src_font_dir + "\" does not exist");
}
}
//std::cout << "Font " << name << ": " << src_font_dir << "\n";
std::string src_font_css = src_font_dir + ".css";
if (!fs::exists(src_font_css)) {
throw Argument_error(
"Local font CSS file \"" + src_font_css + "\" does not exist");
}
std::string font_copy =
"cp -r " + src_font_css + " " + src_font_dir + " " + output_font_dir;
//std::string files_copy = "cp -r " + basename + " " + font_dir;
//cout << css_copy << "\n" << files_copy << "\n";
//std::cout << system(css_copy.c_str()) << "\n";
//std::cout << system(files_copy.c_str()) << "\n";
if (system(font_copy.c_str()) != 0) {
std::cout << "Font copy command: " << font_copy << "\n";
throw Argument_error("Local font \"" + name + "\" not found");
}
}
}
elements_t status(std::string date, std::string version, std::string copyright)
{
elements_t result {};
@@ -550,7 +479,6 @@ namespace html {
strings_t css_filenames,
strings_t js_filenames,
strings_t local_fonts,
strings_t google_fonts,
std::string logo)
{
if (page_title.empty())
@@ -601,7 +529,7 @@ namespace html {
page_title = title;
result.push_back(
elt("html",
{ head(page_title, css, css_filenames, local_fonts, google_fonts),
{ head(page_title, css, css_filenames, local_fonts),
elt("body", body)
}).attr("lang", "en"));
return result;
@@ -666,12 +594,12 @@ namespace html {
elements_t make_page(
elements_t body,
std::string page_title, std::string css,
strings_t css_filenames, strings_t local_fonts, strings_t google_fonts)
strings_t css_filenames, strings_t local_fonts)
{
elements_t page { preamble() };
page.push_back(
elt("html",
{ head(page_title, css, css_filenames, local_fonts, google_fonts),
{ head(page_title, css, css_filenames, local_fonts),
elt("body", body)
}).attr("lang", "en"));
return page;