Files
klammertext/sks/image/image.py
T
ack 830b19394d Klammertext runs natively on Windows; a Windows source-install guide; the bundled sh for @eval :shell
Assembled from klammertext-dev f344a37d772c. The commands, the library,
the Standard Klammer Set, the reflection klammerset and the Python
binding build and run natively on Windows (MSYS2 UCRT64 gcc, python.org
Python), and both test tiers pass there. doc/install/windows_source_install.md
is the fifth install guide: a source install parallel to the Linux and
macOS ones, verified by following it on a pristine Windows 11.

Behaviour on every system: paths Klammertext prints use forward slashes;
output is LF; the command line is UTF-8 on Windows; @eval :shell is a
POSIX shell command everywhere -- on Windows it runs the sh Klammertext
ships, BusyBox for Windows (win/busybox/, GPLv2, with its licence and the
source pointer). KLAMMERTEXT_FONTS and KLAMMERTEXT_KLAMMERSETS are lists in
the system's PATH convention (';' on Windows). On Linux and macOS nothing
observable changes.
2026-09-25 00:33:26 +02:00

119 lines
4.6 KiB
Python

import sys
import os
_klammertext_home = os.environ.get('KLAMMERTEXT_HOME', os.path.expanduser('~/projects/klammertext/K'))
sys.path.append(os.path.join(_klammertext_home, 'sks/kutil'))
sys.path.append(os.path.join(_klammertext_home, 'sks/target'))
import re
import os
import shutil
import kutil
import html_util
import latex_util
import klammer_base
import image_cache
import pprint
from html_util import E
import sys
class Image(klammer_base.Klammer_base):
id = 0
def __init__(self, K, as_string=True, width=None):
super().__init__(K)
# /dev/shm is a fast RAM-backed tmpfs on Linux; on macOS it does not
# exist, so fall back to the platform temp directory.
cache_dir = "/dev/shm"
if not os.path.isdir(cache_dir):
import tempfile
cache_dir = tempfile.gettempdir()
self.cache = image_cache.Image_cache(cache_dir, self.Image_search_path, verbose=False,
quality=self.Image_quality)
self.basename = klammer_base.unescape_ktesc(self.basename)
self.source, self.pwidth, self.pheight, self.file_error = self.cache.get(self.K_target, self.basename)
if self.file_error:
self.file_error_message = f'\nERROR: Image "{self.basename}" not found'
self.as_string = as_string
if width:
self.width = width
self.rel_image = None
self.rel_fraction = 1.0
if self.rel:
self.rel_image, self.rel_pwidth, self.rel_pheight, self.file_error = self.cache.get(self.K_target, self.rel)
self.rel_fraction = self.pwidth / self.rel_pwidth
if self.file_error:
self.file_error_message = f'\nERROR: Image "{self.rel}" (the :rel image) not found'
def html(self):
img_dir = f"{self.K_output_dir}/{self.K_output_basename}/{self.Image_output_dir}"
if not os.path.exists(img_dir):
os.makedirs(img_dir)
if not os.path.exists(f"{img_dir}/{os.path.basename(self.source)}"):
shutil.copy2(self.source, img_dir)
scale_x, scale_y = 1, 1 # Old
result = E("img")
if self.id:
result.attr("id", self.id)
filename = f"{self.Image_output_dir}/{os.path.basename(self.source)}"
result.attr("src", filename).attr("alt", os.path.basename(filename))
length, value, ltype = kutil.parse_width("html", self.width, self.rel_fraction)
if ltype == "w":
percent = float(value) * 100
result.sty(f"width: {percent}%")
elif ltype == "px":
# The html width ATTRIBUTE takes pixels only; every other unit
# is a style (an attribute of "2em" was silently ignored).
result.attr("width", length)
else:
result.sty(f"width: {length}")
if self.border:
result.cls("image_border")
if self.file_error:
self.caption += self.file_error_message
result = html_util.add_caption(
result, "Figure", self.number, self.caption, self.caption_style,
self.hpos, self.caption_side, False, self.caption_size,
offset=self.offset)
result = E("div").body(result).cls("image_margin")
if self.as_string:
result = str(result) + "\n"
return result
def tex(self):
# Forward slashes: this path is document text (\includegraphics, an
# html src), where a Windows backslash is a TeX command or an escape.
source = os.path.abspath(self.source).replace(os.sep, "/")
width = kutil.parse_width("tex", self.width, self.rel_fraction)[0]
width = re.sub("px", "pt", width)
#result = f'\\includegraphics[width={width}]{{{source}}}'
if self.number or self.caption:
result = f'\\includegraphics[width=\\textwidth]{{{source}}}'
if self.file_error:
self.caption += self.file_error_message
result = latex_util.add_caption(
result, "Figure", self.number, self.caption, width,
self.hpos, self.caption_side, offset=self.offset)
else:
result = f'\\includegraphics[width={width}]{{{source}}}'
result = latex_util.caption_wrapper(result, self.hpos, offset=self.offset)
name = f"Reference-Figure-{Image.id}"
result = f"\\hypertarget{{{name}}}{{}}\\label{{Label-{name}}}\n{result}"
Image.id += 1
# \includegraphics (bare or inside a caption wrapper's minipage) is
# box material: it must sit in vertical mode or it is typeset beside
# any text it follows.
return latex_util.block(result)