#! /usr/bin/env python ############################################### # Convert each utfsym picture to a PDF file. # # # # In fact, this script creates only a Ninja # # build file to perform the conversion and a # # fakeutfsym.sty file that uses the generated # # PDF files. # # # # Author: Scott Pakin # ############################################### import glob import os import re import subprocess import sys import textwrap def kpsewhich(fname, must_exist=True): 'Find a filename in the TeX tree.' proc = subprocess.run(['kpsewhich', fname], capture_output=True, check=must_exist, encoding='utf-8') if proc.returncode != 0: return None return proc.stdout.strip() # If utfsym.sty doesn't exist, write a dummy utfsym.ninja and exit. sty = kpsewhich('utfsym.sty', must_exist=False) if sty is None: with open('utfsym.ninja', 'w') as w: # Write some boilerplate code. w.write('# This is a generated file. DO NOT EDIT.\n') w.write('# Edit %s instead.\n' % os.path.abspath(sys.argv[0])) w.write(''' rule touch command = touch $out build fakeutfsym.sty : touch build UTFSYM : phony fakeutfsym.sty ''') sys.exit(0) # Extract the package description from utfsym.sty. desc_re = re.compile(r'\\ProvidesExplPackage\{utfsym\}(\{.*\})$') with open(sty) as r: for ln in r: match = desc_re.search(ln) if match is not None: desc = match[1] break # Acquire a list of all defined symbols in the form "usym". udir = os.path.dirname(kpsewhich('usym1F600.tikz')) tikz_files = glob.glob(os.path.join(udir, '*.tikz')) symbols = [os.path.splitext(os.path.basename(fn))[0] for fn in tikz_files] symbols.sort(key=lambda s: int(s[4:], 16)) # Generate a Ninja build file for managing PDF creation. with open('utfsym.ninja', 'w') as w: # Write some boilerplate code. w.write('# This is a generated file. DO NOT EDIT.\n') w.write('# Edit %s instead.\n' % os.path.abspath(sys.argv[0])) w.write(r''' rule write-file command = /bin/echo -e '$body' > $out description = Creating $out build utfsym/preloaded.tex : write-file body = $ \\documentclass{minimal}\n$ \\usepackage{utfsym}\n$ \\begin{document}\n$ \\end{document} rule generate-mylatex command = $ cd utfsym ; $ pdflatex --ini '&pdflatex' mylatex.ltx preloaded.tex description = Creating mylatex.fmt for faster builds ''') w.write('build utfsym/mylatex.fmt utfsym/mylatex.log :' ' generate-mylatex utfsym/preloaded.tex | %s %s\n' % (kpsewhich('mylatex.ltx'), kpsewhich('utfsym.sty'))) w.write(r''' rule write-symbol-tex command = bash -c '$ base=$$(basename $out .tex) ; $ sym=$${base:4} ; $ echo -e "$ \\\\documentclass{minimal}\\n$ \\\\begin{document}\\n$ \\\\usym{$$sym}\\n$ \\\\end{document}" > $out' description = Writing $out ''') # For each symbol defined by utfsym.sty, create a LaTeX file. for base in symbols: w.write(f'build utfsym/{base}.tex : write-symbol-tex\n') # Compile each LaTeX file to a PDF file. w.write(r''' rule tex-to-pdf command = $ texname="$$(basename $in)" ; $ jname="$$(basename $in .tex)-uncrop" ; $ cd utfsym ; $ pdflatex -jobname "$$jname" '&mylatex' "$$texname" description = pdflatex $in ''') for base in symbols: w.write(f'build utfsym/{base}-uncrop.pdf utfsym/{base}-uncrop.log utfsym/{base}-uncrop.aux : tex-to-pdf utfsym/{base}.tex | utfsym/mylatex.fmt\n') w.write('\n') # Crop each PDF file. w.write('rule crop-pdf\n') w.write(' command = pdfcrop $in $out\n') w.write(' description = Cropping $in to produce $out\n\n') for sym in symbols: w.write(f'build utfsym/{sym}.pdf : crop-pdf utfsym/{sym}-uncrop.pdf\n') # Create a fakeutfsym.sty file. w.write(r''' build fakeutfsym.sty : write-file body = $ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n$ % This is a generated file. DO NOT EDIT. %\n$ % Edit makefakeutfsym instead. %\n$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n$ \n$''') w.write(r''' \\NeedsTeXFormat{LaTeX2e}\n$ \\ProvidesExplPackage{fakeutfsym}%s\n$ \\RequirePackage{graphicx}\n$ \n$ \\NewDocumentCommand{\\usym}{m}{\\includegraphics{utfsym/usym#1}}\n$ \\NewDocumentCommand{\\usymW}{m m}{\\includegraphics[width=#2]{utfsym/usym#1}}\n$ \\NewDocumentCommand{\\usymH}{m m}{\\includegraphics[height=#2]{utfsym/usym#1}}\n$ \n$ \\endinput ''' % desc) w.write('\n') # Create a phony symbol that depends on fakeutfsym.sty and all # generated PDF files. w.write('build UTFSYM : phony $\n') phony = [f'utfsym/{sym}.pdf' for sym in symbols] + ['fakeutfsym.sty'] lines = textwrap.wrap(' '.join(phony), break_long_words=False, break_on_hyphens=False, initial_indent=' ', subsequent_indent=' ') w.write('%s\n' % ' $\n'.join(lines))