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."