3811b51fa1be4cc168510aa238668265fcb7dc34
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
102 }
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."