Code

font2tex: Install everything to supplier/typeface.
[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 family-code should follow the Karl Berry font naming conventions. See
90 <http://www.tug.org/fontname/fontname.pdf> for details.
92 The font files may be specified in an arbitrary order. font2tex will try to
93 determine which of the files contains regular, bold, and italic fonts. If not
94 italic fonts have been specified, font2tex will try to generate them for you.
96 Copyright (C) 2012 Sebastian 'tokkee' Harl <sh@tokkee.org>
97 This is free software under the terms of the BSD license, see the source for
98 copying conditions. There is NO WARRANTY; not even for MERCHANTABILITY or
99 FITNESS FOR A PARTICULAR PURPOSE.
100 EOF
101         exit $1
104 while getopts MIgT:khxX:s:t:F: arg; do
105         case "$arg" in
106                 M)
107                         domaps=0
108                         ;;
109                 I)
110                         doinstall=0
111                         ;;
112                 g)
113                         target="$( $KPSEWHICH -expand-var \$TEXMFLOCAL )"
114                         target_type="local"
115                         ;;
116                 T)
117                         target="$OPTARG"
118                         target_type="custom"
119                         ;;
120                 k)
121                         keeptmp=1
122                         ;;
124                 h)
125                         exit_usage 0
126                         ;;
128                 x)
129                         fntfont=1
130                         ;;
131                 X)
132                         fntfont=1
133                         fntfont_name="$OPTARG"
134                         ;;
136                 s)
137                         supplier_name="$OPTARG"
138                         ;;
139                 t)
140                         typeface_name="$OPTARG"
141                         ;;
142                 F)
143                         latexfamily="$OPTARG"
144                         ;;
146                 *)
147                         exit_usage 1
148                         ;;
149         esac
150 done
151 shift $(( $OPTIND - 1 ))
153 if test $doinstall -ne 1; then
154         domaps=0
155         keeptmp=1
156 fi
158 if test $# -lt 1; then
159         exit_usage 1
160 fi
162 family_code="$1"
163 shift
165 echo "Using family code '$family_code'"
167 if [ -z "$supplier_name" ]; then
168         supplier_name=$( grep "^$( echo $family_code | cut -c1 )" \
169                 "$supplier_map" | cut -d' ' -f2 )
170 fi
171 if test -n "$supplier_name"; then
172         echo "Using supplier name '$supplier_name'"
173 fi
175 if [ -z "$typeface_name" ]; then
176         typeface_name=$( grep "^$( echo $family_code | cut -c2-3 )" \
177                 "$typeface_map" | cut -d' ' -f2 )
178 fi
179 if test -n "$typeface_name"; then
180         echo "Using type-face name '$typeface_name'"
181 fi
183 if [ -z "$supplier_name" -o -z "$typeface_name" ]; then
184         echo "Supplier or typeface codes not known." >&2
185         echo "Aborting!" >&2
186         exit 1
187 fi
189 tmpdir=$( mktemp -d -t font2tex.XXXXXXXXXX )
190 if test $keeptmp -eq 0; then
191         trap "rm -rf $tmpdir" EXIT
192 else
193         trap "echo \"Not removing temporary directory '$tmpdir' as requested.\"" EXIT
194 fi
195 echo "Using temporary directory '$tmpdir'."
197 regular_font=""
198 bold_font=""
199 italic_font=""
200 bold_italic_font=""
202 while test $# -gt 0; do
203         font_file="$1"
204         font_type="${font_file##*.}"
205         shift
207         if test "$font_file" = "$font_type"; then
208                 echo "Failed to determine file extension for '$font_file'." >&2
209                 exit 1
210         fi
212         font_weight="$( $FONTFORGE -lang=ff \
213                 -c "Open('$font_file', 1); Print(\$weight)" 2> /dev/null )"
214         font_italicangle="$( $FONTFORGE -lang=ff \
215                 -c "Open('$font_file', 1); Print(\$italicangle)" 2> /dev/null )"
217         case "$font_weight-$font_italicangle" in
218                 Regular-0)
219                         if test -n "$regular_font"; then
220                                 echo "Multiple candidates for regular font:" \
221                                         "$regular_font, $font_file" >&2
222                                 exit 1
223                         fi
224                         echo "Using regular font '$font_file'"
225                         cp "$font_file" "$tmpdir/${family_code}r8a.$font_type"
226                         regular_font="${family_code}r8a.$font_type"
227                         ;;
228                 Regular-?[0-9]*)
229                         if test -n "$italic_font"; then
230                                 echo "Multiple candidates for italic font:" \
231                                         "$italic_font, $font_file" >&2
232                                 exit 1
233                         fi
234                         echo "Using italic font '$font_file'"
235                         cp "$font_file" "$tmpdir/${family_code}ri8a.$font_type"
236                         italic_font="${family_code}ri8a.$font_type"
237                         ;;
238                 Medium-0|Bold-0)
239                         if test -n "$bold_font"; then
240                                 echo "Multiple candidates for bold font:" \
241                                         "$bold_font, $font_file" >&2
242                                 exit 1
243                         fi
244                         echo "Using bold font '$font_file'"
245                         cp "$font_file" "$tmpdir/${family_code}b8a.$font_type"
246                         bold_font="${family_code}b8a.$font_type"
247                         ;;
248                 Medium*-?[0-9]*|Bold*-?[0-9]*)
249                         if test -n "$bold_italic_font"; then
250                                 echo "Multiple candidates for bold italic font:" \
251                                         "$bold_italic_font, $font_file" >&2
252                                 exit 1
253                         fi
254                         echo "Using bold italic font '$font_file'"
255                         cp "$font_file" "$tmpdir/${family_code}bi8a.$font_type"
256                         bold_italic_font="${family_code}bi8a.$font_type"
257                         ;;
258                 *)
259                         echo "Failed to parse font weight ($font_weight) /" \
260                                 "italic angle ($font_italicange)" >&2
261                         exit 1
262                         ;;
263         esac
264 done
266 cd $tmpdir
268 if test -z "$regular_font" -o -z "$bold_font"; then
269         echo "Failed to determine regular and/or bold font." >&2
270         echo "Aborting!" >&2
271         exit 1
272 fi
274 if test -z "$italic_font"; then
275         font_type="${regular_font##*.}"
276         echo "Generating italic font for you."
277         $FONTFORGE -lang=ff \
278                 -c "Open('$regular_font', 1);
279                         SelectAll();
280                         Skew(13);
281                         SetItalicAngle(-13);
282                         SetFontNames(\$fontname + '-Italic', \$familyname + '-Italic', \$fullname + ' Italic');
283                         Generate('${family_code}ri8a.$font_type');"
284 fi
286 if test -z "$bold_italic_font"; then
287         font_type="${bold_font##*.}"
288         echo "Generating bold italic font for you."
289         $FONTFORGE -lang=ff \
290                 -c "Open('$bold_font', 1);
291                         SelectAll();
292                         Skew(13);
293                         SetItalicAngle(-13);
294                         SetFontNames(\$fontname + '-Italic', \$familyname + '-Italic', \$fullname + ' Italic');
295                         Generate('${family_code}bi8a.$font_type');"
296 fi
298 for T in r b ri bi; do
299         in="$( ls ${family_code}${T}8a.* )"
300         out="${family_code}${T}8a.pfb"
301         if test -z "$in"; then
302                 echo "Internal error: Failed to find input file (T=$T)!" >&2
303                 exit 5
304         fi
305         $FONTFORGE -lang=ff -c "Open('$in', 1); Generate('$out')"
306 done
308 cat <<EOF > "$family_code-drv.tex"
309 \\input fontinst.sty
310 \\recordtransforms{$family_code-rec.tex}
311 \\latinfamily{$family_code}{}
312 \\endrecordtransforms
313 \\bye
314 EOF
315 $TEX "$family_code-drv.tex"
317 for f in *.pl; do
318         pltotf $f
319 done
321 for f in *.vpl; do
322         vptovf $f
323 done
325 date=$( date +%Y/%m/%d )
326 cat <<EOF > "$typeface_name.sty"
327 \\NeedsTeXFormat{LaTeX2e}
328 \\ProvidesPackage{$typeface_name}[$date v0.1 $supplier_name $typeface_name for LaTeX]
329 \\renewcommand*{\\${latexfamily}default}{$family_code}
330 \\endinput
331 EOF
333 cat <<EOF > "$family_code-map.tex"
334 \\input finstmsc.sty
335 \\resetstr{PSfontsuffix}{.pfb}
336 \\adddriver{dvips}{$family_code.map}
337 \\input $family_code-rec.tex
338 \\donedrivers
339 \\bye
340 EOF
341 $TEX "$family_code-map.tex"
343 if test $doinstall -ne 1; then
344         echo "Successfully created LaTeX font for $family_code."
345         echo "Skipping installation of the font as requested."
346         exit 0
347 fi
349 mkdir -p "$target"/fonts/{afm,tfm,type1,vf}/"$supplier_name/$typeface_name"
350 for s in afm tfm vf; do
351         cp *.$s "$target/fonts/$s/$supplier_name/$typeface_name"
352 done
353 cp *.pfb "$target/fonts/type1/$supplier_name/$typeface_name"
354 mkdir -p "$target/tex/latex/$supplier_name/$typeface_name"
356 cp *.fd *.sty "$target/tex/latex/$supplier_name/$typeface_name"
358 mkdir -p "$target"/fonts/map/{dvips,pdftex}/"$supplier_name/$typeface_name"
359 cp "$family_code.map" "$target/fonts/map/dvips/$supplier_name/$typeface_name"
360 cp "$family_code.map" "$target/fonts/map/pdftex/$supplier_name/$typeface_name"
362 $MKTEXLSR "$target"
364 if test $domaps -eq 1; then
365         case $target_type in
366                 system)
367                         updmap-sys --force --enable Map="$family_code.map"
368                         ;;
369                 home)
370                         updmap --force --enable Map="$family_code.map"
371                         ;;
372                 *)
373                         TEXMFHOME="$target" updmap \
374                                 --dvipsoutputdir "$target"/var/fonts/map/dvips/updmap \
375                                 --pdftexoutputdir "$target"/var/fonts/map/pdftex/updmap \
376                                 --force --enable Map="$family_code.map"
377                         ;;
378         esac
379 fi
381 if test $fntfont -eq 1; then
382         if test -z "$fntfont_name"; then
383                 fntfont_name="${family_code}r8r"
384         fi
385         if test "$target_type" = "custom"; then
386                 export TEXMFVAR="$target/var"
387                 export TEXMFHOME="$target"
388         fi
389         pdftex fntproof "$fntfont_name" '\fonttable\bye'
390         cp fntproof.pdf "$orig_wd"
391 fi
393 echo ""
394 echo "Installed LaTeX font for $family_code to '$target'."
395 if test "$target_type" = "custom"; then
396         echo "Set TEXMFVAR to '$target/var'"
397         echo "and TEXMFHOME to '$target'"
398         echo "when using the font."
399 fi
401 echo "Successfully created and installed LaTeX font for $family_code."