2026-07-18 18:48:23 +02:00
|
|
|
import os
|
|
|
|
|
import re
|
|
|
|
|
import kutil
|
|
|
|
|
import klammer_base
|
|
|
|
|
import image
|
|
|
|
|
import latex_util
|
|
|
|
|
import html
|
|
|
|
|
import html_util
|
|
|
|
|
from html_util import E
|
|
|
|
|
import image_cache
|
|
|
|
|
|
|
|
|
|
#import kutil
|
|
|
|
|
|
|
|
|
|
class Kargs:
|
|
|
|
|
def __init__(self, target, K, **kwargs):
|
|
|
|
|
self.__dict__ = kwargs
|
|
|
|
|
self.center = False
|
|
|
|
|
self.caption_font = "i"
|
|
|
|
|
self.caption_side = "bottom"
|
|
|
|
|
self.caption_side_center = False
|
|
|
|
|
self.Image_search_path = K.Image_search_path
|
|
|
|
|
self.number = K.cell_number
|
|
|
|
|
self.hpos = "none"
|
|
|
|
|
self.K_target = target
|
|
|
|
|
self.K_input_filenames = K.K_input_filenames
|
|
|
|
|
self.K_output_dir = K.K_output_dir
|
|
|
|
|
self.K_output_basename = K.K_output_basename
|
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).
2026-07-22 18:17:43 +02:00
|
|
|
self.Image_output_dir = K.Image_output_dir
|
2026-07-18 18:48:23 +02:00
|
|
|
self.K_toc_only = False
|
|
|
|
|
self.id = ""
|
|
|
|
|
self.as_string = False
|
|
|
|
|
self.rel = None
|
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).
2026-07-22 18:17:43 +02:00
|
|
|
# Defaults for @image parameters the grid does not use per cell.
|
|
|
|
|
self.border = False
|
|
|
|
|
self.vmargin = False
|
|
|
|
|
self.abswidth = 0.0
|
|
|
|
|
self.caption_font_size = .9
|
2026-07-18 18:48:23 +02:00
|
|
|
|
|
|
|
|
def img(K, target, basename, caption, width):
|
|
|
|
|
result = image.Image(
|
|
|
|
|
Kargs(target, K, basename=basename, caption=caption), width=width)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
class Image_grid(klammer_base.Klammer_base):
|
|
|
|
|
def __init__(self, K):
|
|
|
|
|
super().__init__(K)
|
|
|
|
|
self.K = K
|
|
|
|
|
image_pat = re.compile("([^\s]+)\s*(.*?)", re.S)
|
|
|
|
|
|
|
|
|
|
self.images = []
|
|
|
|
|
self.basenames = []
|
|
|
|
|
self.captions = []
|
|
|
|
|
|
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).
2026-07-22 18:17:43 +02:00
|
|
|
for row in self.image_specs:
|
2026-07-18 18:48:23 +02:00
|
|
|
self.images.append(
|
|
|
|
|
[e.groups() for e in [image_pat.fullmatch(s.strip()) for s in row]])
|
|
|
|
|
self.basenames.append([e[0] for e in self.images[-1]])
|
|
|
|
|
self.captions.append([e[1] for e in self.images[-1]])
|
|
|
|
|
self.cache = image_cache.Image_cache(
|
|
|
|
|
os.path.dirname(os.path.abspath(self.K_input_filenames)),
|
|
|
|
|
self.Image_search_path,
|
|
|
|
|
verbose=False)
|
|
|
|
|
|
|
|
|
|
self.margin = 0.01
|
|
|
|
|
|
|
|
|
|
self.grid = []
|
|
|
|
|
for basenames, captions in zip(self.basenames, self.captions):
|
|
|
|
|
cell_widths = self.widths(self.K_target, basenames)
|
|
|
|
|
row = []
|
|
|
|
|
for basename, caption, cell_width in zip(basenames, captions, cell_widths):
|
|
|
|
|
row.append([basename, caption, cell_width])
|
|
|
|
|
self.grid.append(row)
|
|
|
|
|
|
|
|
|
|
def widths(self, target, basenames):
|
|
|
|
|
dims = []
|
|
|
|
|
for basename in basenames:
|
|
|
|
|
dims.append(self.cache.get("html", basename))
|
|
|
|
|
heights = [e[2] for e in dims]
|
|
|
|
|
total_height = sum(heights)
|
|
|
|
|
height_scales = [h/total_height for h in heights]
|
|
|
|
|
widths = [e[1] for e in dims]
|
|
|
|
|
widths = [e[0] / e[1] for e in zip(widths, height_scales)]
|
|
|
|
|
total_width = sum(widths)
|
|
|
|
|
margin = self.margin * total_width
|
|
|
|
|
total_width += margin * (len(widths) - 1)
|
|
|
|
|
result = [w/total_width for w in widths]
|
|
|
|
|
result = [f"{w:0.6f}w" for w in result]
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
def html(self):
|
|
|
|
|
result = ""
|
|
|
|
|
for row in self.grid:
|
|
|
|
|
row_cells = ""
|
|
|
|
|
for basename, caption, cell_width in row:
|
|
|
|
|
cell_image = img(self.K, "html", basename, caption, cell_width).html()
|
|
|
|
|
row_cells += str(cell_image).strip() + "\n"
|
|
|
|
|
result += str(E("div").body(row_cells).cls("image_grid_row").attr("data-row-size", len(row)))
|
|
|
|
|
result = E("div").body(result).cls("image_grid")
|
|
|
|
|
if self.number or self.caption:
|
|
|
|
|
result = html_util.add_caption(result, "Figure", self.number, self.caption)
|
|
|
|
|
return str(result)
|
|
|
|
|
|
|
|
|
|
def tex(self):
|
|
|
|
|
result = ""
|
|
|
|
|
for row in self.grid:
|
|
|
|
|
row_cells = ""
|
|
|
|
|
for basename, caption, cell_width in row:
|
|
|
|
|
cell_image = img(self.K, "tex", basename, caption, cell_width).tex()
|
|
|
|
|
row_cells += str(cell_image).strip() + f"\\hspace*{{{self.margin}\\textwidth}}%\n"
|
|
|
|
|
#result += "\\begin{minipage}[t]{\\textwidth}" \
|
|
|
|
|
# + f"{{{row_cells}}}\n\\end{{minipage}}
|
|
|
|
|
result += latex_util.minipage(row_cells, vertical="t") + f"\\\\[{self.margin}\\textwidth]\n"
|
|
|
|
|
if self.number or self.caption:
|
|
|
|
|
result = latex_util.add_caption(
|
|
|
|
|
result.strip(), "Figure", self.number, self.caption, "\\textwidth")
|
|
|
|
|
else:
|
|
|
|
|
#result = f"\\begin{{minipage}}{{\\textwidth}}\n\\centering {result}\n\\end{{minipage}}\n"
|
|
|
|
|
result = latex_util.minipage("\\centering " + result, vertical="t") + "\n"
|
|
|
|
|
return result
|