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

@@ -5,7 +5,7 @@ K := $(KLAMMERTEXT_HOME)
KS := $(K)/sks
KM := $(K)/mac
include $(KM)/env/makefile.env
include $(K)/env/makefile.env
# Additional include paths for sks components
LOCAL_CPPFLAGS := -I$(KM) -I$(KS)/kutil -I$(KS)/target
@@ -23,8 +23,7 @@ LOCAL_DEPFILES := document_class.d document_html.d document_latex.d heading.d re
# External object files from sks/ (mac/*.o now in libklammertext.so)
SKS_OBJECTS := $(KS)/kutil/kutil.o $(KS)/kutil/klammer_base.o \
$(KS)/target/html_util.o $(KS)/target/latex_util.o \
$(KS)/target/font_resolve.o
$(KS)/target/html_util.o $(KS)/target/latex_util.o
ALL_OBJECTS := $(LOCAL_OBJECTS) $(SKS_OBJECTS)

View File

@@ -1,8 +1,10 @@
@@@argtype document_structure |
Structure of a document: plain, article, or book
:pattern plain^|article^|book
:default plain
@@@
@@document.k
:title
:subtitle
@@ -19,7 +21,7 @@
:toc.bool false
]#
:structure.document_structure plain
:structure.document_structure
:text
:files
@@ -38,9 +40,6 @@
:include_sks_js.bool true
:include_fonts.bool true
:local_fonts.list linux-libertine
:google_fonts.list Inconsolata Open+Sans:wght^@500 Libre+Baskerville
:serif_font Crimson Pro
:sans_font Open Sans
:mono_font Inconsolata

View File

@@ -62,8 +62,6 @@ Document_class::Document_class(Machine& machine) : Klammer_base(machine)
m_include_sks_js = strbool(get("include_sks_js"), loc);
// font_dirs = word_split(get("font_dirs"));
m_local_fonts = word_split(get("local_fonts"));
m_google_fonts = word_split(get("google_fonts"));
auto strip_quotes = [](std::string s) {
if (s.size() >= 2 && s.front() == '"' && s.back() == '"')

View File

@@ -5,7 +5,7 @@
#include "latex_util.h"
#include "machine.h"
#include "heading.h"
#include "font_resolve.h"
#include "font_store.h"
const std::string closed_symbol { "&^#9656;" };
const std::string open_symbol { "&^#9662;" };
@@ -120,8 +120,6 @@ public:
bool m_include_sks_js = true;
strings_t m_font_dirs {};
strings_t m_local_fonts {};
strings_t m_google_fonts {};
std::string m_serif_font {};
std::string m_sans_font {};

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,