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

@@ -87,8 +87,7 @@ strings_t Document_class::resolved_font_names()
{
strings_t result {};
auto add = [&](const Resolved_font& rf) {
if (!rf.family_name.empty() &&
std::find(m_local_fonts.begin(), m_local_fonts.end(), rf.dir_name) == m_local_fonts.end())
if (!rf.family_name.empty())
result.push_back(rf.dir_name);
};
add(m_resolved_serif);
@@ -101,13 +100,17 @@ std::string Document_class::font_definitions()
{
std::stringstream ss {};
if (!m_serif_font.empty() || !m_sans_font.empty() || !m_mono_font.empty()) {
// Family names are quoted: an unquoted name with a digit-initial
// word ("Source Sans 3") is invalid CSS, and a font-family using
// var() with such a value computes to inherit, silently losing
// the font.
ss << ":root {\n";
if (!m_serif_font.empty())
ss << " --serif: " << m_serif_font << ", serif;\n";
ss << " --serif: \"" << m_serif_font << "\", serif;\n";
if (!m_sans_font.empty())
ss << " --sans-serif: " << m_sans_font << ", sans-serif;\n";
ss << " --sans-serif: \"" << m_sans_font << "\", sans-serif;\n";
if (!m_mono_font.empty())
ss << " --monospace: " << m_mono_font << ", monospace;\n";
ss << " --monospace: \"" << m_mono_font << "\", monospace;\n";
ss << "}\n";
}
// Emit scale factors so sans and mono fonts match the serif font.
@@ -180,7 +183,6 @@ std::string Document_class::create_html_output_directories()
if (!file_exists(output_directory)) {
fs::create_directory(output_directory);
}
html::install_local_fonts(m_font_dirs, m_local_fonts, output_directory);
install_resolved_font(m_resolved_serif, output_directory);
install_resolved_font(m_resolved_sans, output_directory);
install_resolved_font(m_resolved_mono, output_directory);
@@ -665,13 +667,9 @@ elements_t Document_class::page(std::string body_text, std::string output_dir, i
std::string page_title = m_page_title.empty() ? m_title : m_page_title;
strings_t all_local_fonts = m_local_fonts;
for (auto& name : resolved_font_names())
all_local_fonts.push_back(name);
elements_t page = html::make_page(
body, page_title,
css_text, css_filenames, all_local_fonts, m_google_fonts);
css_text, css_filenames, resolved_font_names());
return page;
}
@@ -734,10 +732,7 @@ std::string Document_class::make_html_navigation_structure(
m_file_components[0].second,
m_date, m_version, m_copyright,
css_text, all_css_files, all_js_files,
[&]() { strings_t f = m_local_fonts;
for (auto& n : resolved_font_names()) f.push_back(n);
return f; }(),
m_google_fonts,
resolved_font_names(),
m_logo);
std::string result = t.str();
result = string_replace(result,