#! /usr/bin/env python ################################################### # Convert each worldflags picture to a PDF file. # # # # In fact, this script creates only a Ninja # # build file to perform the conversion and a # # fakeworldflags.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 worldflags.sty doesn't exist, write a dummy worldflags.ninja and exit. sty = kpsewhich('worldflags.sty', must_exist=False) if sty is None: with open('worldflags.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 fakeworldflags.sty : touch build WORLDFLAGS : phony fakeworldflags.sty ''') sys.exit(0) # Extract the package date from worldflags.sty. wfdate_re = re.compile(r'(\d\d\d\d)-(\d\d)-(\d\d)') with open(sty) as r: for ln in r: match = wfdate_re.search(ln) if match is not None: wfdate = match[1] + '/' + match[2] + '/' + match[3] break # Acquire a list of all defined symbols. wfdir = os.path.dirname(kpsewhich('worldflag_US.tex')) tex_files = glob.glob(os.path.join(wfdir, '*.tex')) flags = [os.path.splitext(os.path.basename(fn))[0][10:] for fn in tex_files] flags.sort() # Generate a Ninja build file for managing PDF creation. with open('worldflags.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 worldflags/preloaded.tex : write-file body = $ \\documentclass{minimal}\n$ \\usepackage{worldflags}\n$ \\begin{document}\n$ \\end{document} rule generate-mylatex command = $ cd worldflags ; $ pdflatex --ini '&pdflatex' mylatex.ltx preloaded.tex description = Creating mylatex.fmt for faster builds ''') w.write('build worldflags/mylatex.fmt worldflags/mylatex.log :' ' generate-mylatex worldflags/preloaded.tex | %s %s\n' % (kpsewhich('mylatex.ltx'), kpsewhich('worldflags.sty'))) w.write(r''' rule write-symbol-tex command = bash -c '$ base=$$(basename $out .tex) ; $ sym=$${base:5} ; $ echo -e "$ \\\\documentclass{minimal}\\n$ \\\\begin{document}\\n$ \\\\worldflag[width=9pt]{$$sym}\\n$ \\\\end{document}" > $out' description = Writing $out ''') # For each symbol defined by worldflags.sty, create a LaTeX file. for abbr in flags: w.write(f'build worldflags/flag_{abbr}.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 worldflags ; $ pdflatex -jobname "$$jname" '&mylatex' "$$texname" description = pdflatex $in ''') for abbr in flags: base = 'flag_' + abbr w.write(f'build worldflags/{base}-uncrop.pdf worldflags/{base}-uncrop.log worldflags/{base}-uncrop.aux : tex-to-pdf worldflags/{base}.tex | worldflags/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 abbr in flags: base = 'flag_' + abbr w.write(f'build worldflags/{base}.pdf : crop-pdf worldflags/{base}-uncrop.pdf\n') # Create a fakeworldflags.sty file. w.write(r''' build fakeworldflags.sty : write-file body = $ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n$ % This is a generated file. DO NOT EDIT. %\n$ % Edit makefakeworldflags instead. %\n$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n$ \n$ ''') w.write(r''' \\NeedsTeXFormat{LaTeX2e}\n$ \\ProvidesPackage{fakeworldflags}[%s v0.0 Flags of the world]\n$ \\RequirePackage{graphicx}\n$ \n$ \\newcommand*{\worldflag}[1]{\\includegraphics{worldflags/flag_#1}}\n$ \n$ \\endinput '''[1:] % wfdate) w.write('\n') # Create a phony symbol that depends on fakeworldflags.sty and all # generated PDF files. w.write('build WORLDFLAGS : phony $\n') phony = [f'worldflags/flag_{abbr}.pdf' for abbr in flags] + \ ['fakeworldflags.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))