Code

Initial commit; imported font2tex.sh helper script.
[tokkeeutils.git] / tex / font2tex.sh
1 #! /bin/bash
2 #
3 # Copyright (C) 2012 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #
28 # This script may be used to convert various font formats
29 # to fonts usable by LaTeX.
30 #
32 set -e
33 set -u
35 orig_wd="$( pwd )"
37 KPSEWHICH="$( which kpsewhich )"
38 FONTFORGE="$( which fontforge )"
39 MKTEXLSR="$( which mktexlsr )"
40 TEX="$( which tex )"
42 supplier_map="$( $KPSEWHICH supplier.map )"
43 typeface_map="$( $KPSEWHICH typeface.map )"
45 target="$( $KPSEWHICH -expand-var \$TEXMFHOME )"
46 target_type="home"
48 keeptmp=0
49 domaps=1
50 doinstall=1
52 fntfont=0
53 fntfont_name=""
55 supplier_name=""
56 typeface_name=""
57 latexfamily=rm
59 function exit_usage() {
60 cat <<EOF
61 Usage: font2tex [-M] [-I] [-g | -T dir] [-k] [-h] [-T]
62                 [-s supplier] [-t face] [-F rm|sf|tt]
63                 family-code font-file [font-file [...]]
65 Options:
66   -M        Do not register map file
67   -I        Do not install the fonts (implies -k and -M)
68   -g        Install fonts globally (\$TEXMFLOCAL = $( $KPSEWHICH -expand-var \$TEXMFLOCAL ))
69             (Default: \$TEXMFHOME = $( $KPSEWHICH -expand-var \$TEXMFHOME ))
70   -T DIR    Install fonts to the specified target directory rather than any of
71             the texmf directories.
72   -k        Keep temporary directory used to store intermediate files
73   -h        Display this help and exit
75   -x        Create a font test document (fntproof.pdf in your cwd)
76             (By default, the regular series of the font will be used unless
77             another font name is specified using the -X option)
78   -X FONT   Specify the font name to be used to be used for the test document
79             (implies -x; see that option for more details)
81   -s SUPP   Specify supplier name
82             (Default is to determine that from the family name)
83   -t FACE   Specify typeface name
84             (Default is to determine that from the family name)
86   -F FAM    Specify LaTeX font family name
87             (Default: rm)
89 The font files may be specified in an arbitrary order. font2tex will try to
90 determine which of the files contains regular, bold, and italic fonts. If not
91 italic fonts have been specified, font2tex will try to generate them for you.
93 Copyright (C) 2012 Sebastian 'tokkee' Harl <sh@tokkee.org>
94 This is free software under the terms of the BSD license, see the source for
95 copying conditions. There is NO WARRANTY; not even for MERCHANTABILITY or
96 FITNESS FOR A PARTICULAR PURPOSE.
97 EOF
98         exit $1
99 }
101 while getopts MIgT:khxX:s:t:F: arg; do
102         case "$arg" in
103                 M)
104                         domaps=0
105                         ;;
106                 I)
107                         doinstall=0
108                         ;;
109                 g)
110                         target="$( $KPSEWHICH -expand-var \$TEXMFLOCAL )"
111                         target_type="local"
112                         ;;
113                 T)
114                         target="$OPTARG"
115                         target_type="custom"
116                         ;;
117                 k)
118                         keeptmp=1
119                         ;;
121                 h)
122                         exit_usage 0
123                         ;;
125                 x)
126                         fntfont=1
127                         ;;
128                 X)
129                         fntfont=1
130                         fntfont_name="$OPTARG"
131                         ;;
133                 s)
134                         supplier_name="$OPTARG"
135                         ;;
136                 t)
137                         typeface_name="$OPTARG"
138                         ;;
139                 F)
140                         latexfamily="$OPTARG"
141                         ;;
143                 *)
144                         exit_usage 1
145                         ;;
146         esac
147 done
148 shift $(( $OPTIND - 1 ))
150 if test $doinstall -ne 1; then
151         domaps=0
152         keeptmp=1
153 fi
155 if test $# -lt 1; then
156         exit_usage 1
157 fi
159 family_code="$1"
160 shift
162 echo "Using family code '$family_code'"
164 if [ -z "$supplier_name" ]; then
165         supplier_name=$( grep "^$( echo $family_code | cut -c1 )" \
166                 "$supplier_map" | cut -d' ' -f2 )
167 fi
168 if test -n "$supplier_name"; then
169         echo "Using supplier name '$supplier_name'"
170 fi
172 if [ -z "$typeface_name" ]; then
173         typeface_name=$( grep "^$( echo $family_code | cut -c2-3 )" \
174                 "$typeface_map" | cut -d' ' -f2 )
175 fi
176 if test -n "$typeface_name"; then
177         echo "Using type-face name '$typeface_name'"
178 fi
180 if [ -z "$supplier_name" -o -z "$typeface_name" ]; then
181         echo "Supplier or typeface codes not known." >&2
182         echo "Aborting!" >&2
183         exit 1
184 fi
186 tmpdir=$( mktemp -d -t font2tex.XXXXXXXXXX )
187 if test $keeptmp -eq 0; then
188         trap "rm -rf $tmpdir" EXIT
189 else
190         trap "echo \"Not removing temporary directory '$tmpdir' as requested.\"" EXIT
191 fi
192 echo "Using temporary directory '$tmpdir'."
194 regular_font=""
195 bold_font=""
196 italic_font=""
197 bold_italic_font=""
199 while test $# -gt 0; do
200         font_file="$1"
201         font_type="${font_file##*.}"
202         shift
204         if test "$font_file" = "$font_type"; then
205                 echo "Failed to determine file extension for '$font_file'." >&2
206                 exit 1
207         fi
209         font_weight="$( $FONTFORGE -lang=ff \
210                 -c "Open('$font_file', 1); Print(\$weight)" 2> /dev/null )"
211         font_italicangle="$( $FONTFORGE -lang=ff \
212                 -c "Open('$font_file', 1); Print(\$italicangle)" 2> /dev/null )"
214         case "$font_weight-$font_italicangle" in
215                 Regular-0)
216                         if test -n "$regular_font"; then
217                                 echo "Multiple candidates for regular font:" \
218                                         "$regular_font, $font_file" >&2
219                                 exit 1
220                         fi
221                         echo "Using regular font '$font_file'"
222                         cp "$font_file" "$tmpdir/${family_code}r8a.$font_type"
223                         regular_font="${family_code}r8a.$font_type"
224                         ;;
225                 Regular-?[0-9]*)
226                         if test -n "$italic_font"; then
227                                 echo "Multiple candidates for italic font:" \
228                                         "$italic_font, $font_file" >&2
229                                 exit 1
230                         fi
231                         echo "Using italic font '$font_file'"
232                         cp "$font_file" "$tmpdir/${family_code}ri8a.$font_type"
233                         italic_font="${family_code}ri8a.$font_type"
234                         ;;
235                 Medium-0|Bold-0)
236                         if test -n "$bold_font"; then
237                                 echo "Multiple candidates for bold font:" \
238                                         "$bold_font, $font_file" >&2
239                                 exit 1
240                         fi
241                         echo "Using bold font '$font_file'"
242                         cp "$font_file" "$tmpdir/${family_code}b8a.$font_type"
243                         bold_font="${family_code}b8a.$font_type"
244                         ;;
245                 Medium*-?[0-9]*|Bold*-?[0-9]*)
246                         if test -n "$bold_italic_font"; then
247                                 echo "Multiple candidates for bold italic font:" \
248                                         "$bold_italic_font, $font_file" >&2
249                                 exit 1
250                         fi
251                         echo "Using bold italic font '$font_file'"
252                         cp "$font_file" "$tmpdir/${family_code}bi8a.$font_type"
253                         bold_italic_font="${family_code}bi8a.$font_type"
254                         ;;
255                 *)
256                         echo "Failed to parse font weight ($font_weight) /" \
257                                 "italic angle ($font_italicange)" >&2
258                         exit 1
259                         ;;
260         esac
261 done
263 cd $tmpdir
265 if test -z "$regular_font" -o -z "$bold_font"; then
266         echo "Failed to determine regular and/or bold font." >&2
267         echo "Aborting!" >&2
268         exit 1
269 fi
271 if test -z "$italic_font"; then
272         font_type="${regular_font##*.}"
273         echo "Generating italic font for you."
274         $FONTFORGE -lang=ff \
275                 -c "Open('$regular_font', 1);
276                         SelectAll();
277                         Skew(13);
278                         SetItalicAngle(-13);
279                         SetFontNames(\$fontname + '-Italic', \$familyname + '-Italic', \$fullname + ' Italic');
280                         Generate('${family_code}ri8a.$font_type');"
281 fi
283 if test -z "$bold_italic_font"; then
284         font_type="${bold_font##*.}"
285         echo "Generating bold italic font for you."
286         $FONTFORGE -lang=ff \
287                 -c "Open('$bold_font', 1);
288                         SelectAll();
289                         Skew(13);
290                         SetItalicAngle(-13);
291                         SetFontNames(\$fontname + '-Italic', \$familyname + '-Italic', \$fullname + ' Italic');
292                         Generate('${family_code}bi8a.$font_type');"
293 fi
295 for T in r b ri bi; do
296         in="$( ls ${family_code}${T}8a.* )"
297         out="${family_code}${T}8a.pfb"
298         if test -z "$in"; then
299                 echo "Internal error: Failed to find input file (T=$T)!" >&2
300                 exit 5
301         fi
302         $FONTFORGE -lang=ff -c "Open('$in', 1); Generate('$out')"
303 done
305 cat <<EOF > "$family_code-drv.tex"
306 \\input fontinst.sty
307 \\recordtransforms{$family_code-rec.tex}
308 \\latinfamily{$family_code}{}
309 \\endrecordtransforms
310 \\bye
311 EOF
312 $TEX "$family_code-drv.tex"
314 for f in *.pl; do
315         pltotf $f
316 done
318 for f in *.vpl; do
319         vptovf $f
320 done
322 date=$( date +%Y/%m/%d )
323 cat <<EOF > "$typeface_name.sty"
324 \\NeedsTeXFormat{LaTeX2e}
325 \\ProvidesPackage{$typeface_name}[$date v0.1 $supplier_name $typeface_name for LaTeX]
326 \\renewcommand*{\\${latexfamily}default}{$family_code}
327 \\endinput
328 EOF
330 cat <<EOF > "$family_code-map.tex"
331 \\input finstmsc.sty
332 \\resetstr{PSfontsuffix}{.pfb}
333 \\adddriver{dvips}{$family_code.map}
334 \\input $family_code-rec.tex
335 \\donedrivers
336 \\bye
337 EOF
338 $TEX "$family_code-map.tex"
340 if test $doinstall -ne 1; then
341         echo "Successfully created LaTeX font for $family_code."
342         echo "Skipping installation of the font as requested."
343         exit 0
344 fi
346 mkdir -p "$target"/fonts/{afm,tfm,type1,vf}/"$supplier_name/$typeface_name"
347 for s in afm tfm vf; do
348         cp *.$s "$target/fonts/$s/$supplier_name/$typeface_name"
349 done
350 cp *.pfb "$target/fonts/type1/$supplier_name/$typeface_name"
351 mkdir -p "$target/tex/latex/$supplier_name-$typeface_name"
353 cp *.fd *.sty "$target/tex/latex/$supplier_name-$typeface_name"
355 mkdir -p "$target"/fonts/map/{dvips,pdftex}/"$supplier_name/$typeface_name"
356 cp "$family_code.map" "$target/fonts/map/dvips/$supplier_name/$typeface_name"
357 cp "$family_code.map" "$target/fonts/map/pdftex/$supplier_name/$typeface_name"
359 $MKTEXLSR "$target"
361 if test $domaps -eq 1; then
362         case $target_type in
363                 system)
364                         updmap-sys --force --enable Map="$family_code.map"
365                         ;;
366                 home)
367                         updmap --force --enable Map="$family_code.map"
368                         ;;
369                 *)
370                         TEXMFHOME="$target" updmap \
371                                 --dvipsoutputdir "$target"/var/fonts/map/dvips/updmap \
372                                 --pdftexoutputdir "$target"/var/fonts/map/pdftex/updmap \
373                                 --force --enable Map="$family_code.map"
374                         ;;
375         esac
376 fi
378 if test $fntfont -eq 1; then
379         if test -z "$fntfont_name"; then
380                 fntfont_name="${family_code}r8r"
381         fi
382         if test "$target_type" = "custom"; then
383                 export TEXMFVAR="$target/var"
384                 export TEXMFHOME="$target"
385         fi
386         pdftex fntproof "$fntfont_name" '\fonttable\bye'
387         cp fntproof.pdf "$orig_wd"
388 fi
390 echo ""
391 echo "Installed LaTeX font for $family_code to '$target'."
392 if test "$target_type" = "custom"; then
393         echo "Set TEXMFVAR to '$target/var'"
394         echo "and TEXMFHOME to '$target'"
395         echo "when using the font."
396 fi
398 echo "Successfully created and installed LaTeX font for $family_code."