Assembled from klammertext-dev f344a37d0f6e. 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.
119 lines
4.6 KiB
Python
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)
|