diff options
Diffstat (limited to 'Master/texmf-dist/scripts/fontools/autoinst')
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/autoinst | 2267 |
1 files changed, 1246 insertions, 1021 deletions
diff --git a/Master/texmf-dist/scripts/fontools/autoinst b/Master/texmf-dist/scripts/fontools/autoinst index d9b0665ebf1..52fe14b65b4 100755 --- a/Master/texmf-dist/scripts/fontools/autoinst +++ b/Master/texmf-dist/scripts/fontools/autoinst @@ -4,13 +4,12 @@ ---------------------------------------------------------------------------- - Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011 Marc Penninga. + Copyright (C) 2005-2012 Marc Penninga. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License - as published by the Free Software Foundation, - either version 2 of the License, or (at your option) - any later version. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 2 + of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,11 +17,11 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to - Free Software Foundation, Inc., - 59 Temple Place, - Suite 330, - Boston, MA 02111-1307, + along with this program; if not, write to + Free Software Foundation, Inc., + 59 Temple Place, + Suite 330, + Boston, MA 02111-1307, USA ---------------------------------------------------------------------------- @@ -34,114 +33,107 @@ use strict; use warnings; -use Getopt::Long; +use File::Path (); +use File::Spec (); +use Getopt::Long (); +my ($d, $m, $y) = (localtime time)[3 .. 5]; +my $TODAY = sprintf "%04d/%02d/%02d", $y + 1900, $m + 1, $d; -my $USAGE =<<'END_USAGE'; - -'autoinst' is a wrapper around Eddie Kohler's TypeTools -(http://www.lcdf.org/type/), for installing OpenType fonts in LaTeX. - -Usage: autoinst [options] font[s] - -Possible options: - --encoding=ENC[,ENC] Use ENC as text encoding(s) (default: LY1) - - --(no)ts1 Toggle creation of TS1 fonts - --(no)smallcaps Toggle creation of smallcaps shape - --(no)swash Toggle creation of swash shape - --(no)titling Toggle creation of titling shape - --(no)superiors Toggle creation of fonts with superior characters - --(no)inferiors Toggle creation of fonts with inferior characters - --(no)ornaments Toggle creation of ornament fonts - --(no)fractions Toggle creation of fonts with digits for fractions - - --sanserif Install font as sanserif font - --typewriter Install font as typewriter font - --manual Manual mode (see documentation) - --extra="TEXT" Add TEXT to the command line for 'otftotfm' - - --help Print this text - --verbose Make some noise - - font[s] The fonts (either .otf or .ttf) to install. - -Please report any bugs or suggestions to <marc@penninga.info>. -END_USAGE +=begin Comment + The next three tables map the names of weights, widths and shapes + to NFSS codes. New entries can be added, but the names should be + all lowercase. Also make sure that the NFSS 'series' attribute + (the concatenation of weight and width) is unique! -=begin Comment + The 'book' and 'regular' weights and the 'regular' width are mapped + to an empty string rather than 'm', because the 'm' disappears when + weight and width are combined into the NFSS series (unless *both* are + 'regular', but we deal with that case separately). - The next three tables map the names of weights, widths and shapes - to NFSS codes. New entries can be added without problems, - as long as the name is in all lowercase. - The 'book' and 'regular' weights and the 'regular' width are mapped - to an empty string rather than 'm', because the 'm' disappears when - weight and width are combined into the NFSS series (unless both are - 'regular', but we deal with that case later on). The 'oblique' (aka 'slanted') shape is mapped to 'it' to make things - easier for ourselves. This means the program will fail for font - families that have both italic and oblique shapes, but I doubt + easier for ourselves. This means the program will fail for + font families that have both italic and oblique shapes, but I doubt whether these exist (apart from Computer Modern, of course). - + =end Comment =cut my %FD_WEIGHT = ( - thin => 't', - ultralight => 'ul', - extralight => 'el', - light => 'l', - book => '', - regular => '', - medium => 'mb', - demibold => 'db', - semibold => 'sb', - bold => 'b', - extrabold => 'eb', - black => 'a', # Not 'k': that means 'book' in fontname - extrablack => 'ea', - heavy => 'h', - ultra => 'ub', - ultrabold => 'ub', - ultrablack => 'ua', + thin => 't', + ultralight => 'ul', + extralight => 'el', + light => 'l', + book => '', + regular => '', + medium => 'mb', + demibold => 'db', + demi => 'db', + semibold => 'sb', + bold => 'b', + extrabold => 'eb', + ultra => 'ub', + ultrabold => 'ub', + black => 'k', + extrablack => 'ek', + ultrablack => 'uk', + heavy => 'h', + poster => 'r', ); my %FD_WIDTH = ( - ultracondensed => 'uc', - extracondensed => 'ec', - condensed => 'c', - cond => 'c', - semicondensed => 'sc', - regular => '', - semiextended => 'sx', - extended => 'x', + ultracompressed => 'up', + extracompressed => 'ep', + compressed => 'p', + comp => 'p', + cmp => 'p', + compact => 'p', + ultracondensed => 'uc', + extracondensed => 'ec', + condensed => 'c', + cond => 'c', + narrow => 'n', + semicondensed => 'sc', + regular => '', + semiextended => 'sx', + extended => 'x', + expanded => 'e', + wide => 'w', ); my %FD_SHAPE = ( - roman => 'n', - italic => 'it', - it => 'it', # Fix for (at least) some Linotype fonts - oblique => 'it', - slanted => 'it', - romani => 'n', - romanii => 'it', # Map one of Silentium Pro's two roman shapes to 'it' + roman => 'n', + upright => 'n', + italic => 'it', + ita => 'it', + it => 'it', + cursive => 'it', + kursiv => 'it', + inclined => 'it', + incline => 'it', + oblique => 'it', + slanted => 'it', + slant => 'it', + romani => 'n', # Adobe Silentium Pro has two roman shapes; + romanii => 'it', # we map the second one to 'it' ); + =begin Comment - The following tables are used for deciding which font families and shapes + The following tables are used in deciding which font families and shapes to generate. Each hash governs one of these aspects: - 'figure style' (lining, oldstyle, tabular, proportional, superior, inferior etc.); each of these will become a separate font family. - - 'variant' shape (normal, small caps, swash, titling or textcomp). - + - 'shape' (normal, small caps, swash, titling or textcomp). - Each key in the %FIGURE_STYLE hash names a figure style; the corresponding + + Each key in the %STYLE hash names a figure style; the corresponding value is an anonymous hash with four key/value pairs: - reqd A list of required OpenType features; - this style is built if the font supports at least one + reqd A list of required OpenType features; + this style is built if the font supports at least *one* of these features. nice A list of optional OpenType features; these are used if the font supports them, but don't @@ -149,35 +141,35 @@ my %FD_SHAPE = ( extra Extra options passed to otftotfm when creating this style. shape An anonymous array of 'variant' shapes to build with this figure style. - - Ornaments are treated as a separate 'figure style'. - This may seem a bit funny, but is actually the easiest way to do it. - - - Each key in the %SHAPE hash names a 'variant' shape; the corresponding - value is (again) an anonymous hash with several key/value pairs: + + Ornaments are treated as a separate 'figure style'. + This may seem a bit weird, but is actually the easiest way to do it. + + + Each key in the %SHAPE hash names a shape; the corresponding value + is (again) an anonymous hash with several key/value pairs: code An anonymous hash with two possible keys: 'n' -> the NFSS code to use for this variant shape - if the basic shape is upright; + if the 'basic shape' is upright; 'it' -> the NFSS code to use for this variant shape - if the basic shape is italic, slanted or oblique; - If the 'n' ('it') entry is missing, the upright (italic) + if the 'basic shape' is italic, slanted or oblique; + If the 'n' or 'it' entry is missing, the upright or italic version of this variant shape will not be built. - reqd A list of required OpenType features; - this shape is built if the font supports at least one + reqd A list of required OpenType features; + this shape is built if the font supports at least *one* of these features. nice A list of optional OpenType features; these are used if the font supports them, but don't prevent this shape from being built when missing. extra Extra options passed to otftotfm when creating this shape. - name A string added to the name of the generated font, + name A string added to the name of the generated font, to make it unique. - + =end Comment =cut -my %FIGURE_STYLE = ( +my %STYLE = ( TLF => { reqd => [], nice => ['lnum', 'tnum'], @@ -273,329 +265,329 @@ my %SHAPE = ( ); -# The official names -my %CODING_SCHEME = ( - fontools_ly1 => 'TEX TYPEWRITER AND WINDOWS ANSI', - fontools_t1 => 'EXTENDED TEX FONT ENCODING - LATIN', - fontools_ot1 => 'TEX TEXT', - fontools_ts1 => 'TEX TEXT COMPANION SYMBOLS 1---TS1', -); +############################################################################ -# Default values for the command line arguments -%ARGV = ( - encoding => 'LY1', - textcomp => '2', # 0 = no, 1 = yes, 2 = (enc eq 'T1' ? yes : no) - manual => '0', # 0 = no, 1 = yes - verbose => '0', # 0 = no, 1 = yes - extra => '', - nfss => 'rm', - smallcaps => '1', # 0 = no, 1 = yes - swash => '1', # 0 = no, 1 = yes - titling => '0', # 0 = no, 1 = yes - superiors => '1', # 0 = no, 1 = yes - inferiors => '0', # 0 = no, 1 = yes - ornaments => '1', # 0 = no, 1 = yes - fractions => '0', # 0 = no, 1 = yes -); -my @time = localtime; -my $date = sprintf "%04d/%02d/%02d", $time[5] + 1900, $time[4] + 1, $time[3]; +#----------------------------------------------------------------------- +# The main routine. What else? +#----------------------------------------------------------------------- +sub main { + ARGV::parse_options(); + + my @fonts = map { Fontinfo::parse_fontinfo($_) } @ARGV; + Fontinfo::assert_unique(@fonts); + + # For each font, figure out the shapes, styles and encodings to generate + my @worklist + = cleanup(expand_encodings(expand_shapes(expand_styles(@fonts)))); + + # Organize the worklist by family, encoding, style, series and shape + my %fddata; + for my $item (@worklist) { + my $family = $item->{font}{family}; + my $encoding = $item->{encoding}[1]; + my $style = $item->{style}; + my $series = $item->{font}{fdseries}; + my $shape = $item->{fdshape}; + my $minsize = $item->{font}{minsize}; + my $maxsize = $item->{font}{maxsize}; + + push @{$fddata{$family}{$encoding}{$style}{$series}{$shape}}, + [ $minsize, $maxsize, $item->{fontname} ]; + } + while (my ($fam, $famdata) = each %fddata) { + LaTeX::write_stylefile($fam, $famdata); + while (my ($enc, $encdata) = each %$famdata) { + while (my ($sty, $stydata) = each %$encdata) { + LaTeX::write_fdfile($fam, $enc, $sty, $stydata); + } + } + } -# ----------------------- subroutine definitions ----------------------- + make_commands(@worklist); + return; +} -sub main { - parse_options(); - - my (%already_seen, %commands, @fd_data, $err_msg); - - FONTFILE: - for my $filename (@ARGV) { - my %fontinfo = read_font_info($filename); - my $unique - = join ',', @fontinfo{qw(family width weight shape min max)}; - if ( $already_seen{$unique} - and $already_seen{$unique} ne $filename) { - $err_msg .= <<"END_PARSE_ERROR"; - -ERROR: I've parsed both '$already_seen{$unique}' - and '$filename' as - - Family $fontinfo{family} - Width $fontinfo{width} - Weight $fontinfo{weight} - Shape $fontinfo{shape} - Size $fontinfo{min}-$fontinfo{max} -END_PARSE_ERROR - } - else { - $already_seen{$unique} = $filename; - } +#----------------------------------------------------------------------- +# Determine which figure styles to create for each font; +# return a list of (font, style) tuples +#----------------------------------------------------------------------- +sub expand_styles { + return map { my $font = $_; + map { { font => $font, style => $_ } } + grep { has_reqd($font, $STYLE{$_}) } + keys %STYLE + } + @_; +} - FIGURE_STYLE: - for my $figure_style (keys %FIGURE_STYLE) { - - # Does the font support this figure style? - if ( @{$FIGURE_STYLE{$figure_style}{reqd}} - and not grep { exists $fontinfo{features}{$_} } - @{$FIGURE_STYLE{$figure_style}{reqd}} ) { - next FIGURE_STYLE; - } - - # If so, create all corresponding shapes - my $basic = $FD_SHAPE{$fontinfo{shape}}; - - SHAPE: - for my $shape (@{$FIGURE_STYLE{$figure_style}{shapes}}) { - next SHAPE if not exists $SHAPE{$shape}; - next SHAPE if not exists $SHAPE{$shape}{code}{$basic}; - - # Does the font support this shape? - if ( @{$SHAPE{$shape}{reqd}} - and not grep { exists $fontinfo{features}{$_} } - @{$SHAPE{$shape}{reqd}}) { - next SHAPE; - } - - # Decide which features to use - my @features = grep { exists $fontinfo{features}{$_} } - ( - @{$FIGURE_STYLE{$figure_style}{reqd}}, - @{$FIGURE_STYLE{$figure_style}{nice}}, - @{$SHAPE{$shape}{reqd}}, - @{$SHAPE{$shape}{nice}}, - ); - - # Remove duplicate features - my %tmp_features; - for my $f (@features) { - $tmp_features{$f} = 1; - } - if ($tmp_features{onum} && $tmp_features{lnum}) { - delete $tmp_features{lnum}; - } - @features = keys %tmp_features; - - # Figure out the name and NFSS code for the encodings - my @encodings; - if ($shape eq 'textcomp') { - @encodings = (['fontools_ts1', 'ts1']); - } - elsif ($figure_style eq 'Orn') { - @encodings = ([make_ornament_encoding(%fontinfo), 'u']); - } - else { - @encodings = map { [lc $_, lc $_] } @{$ARGV{encoding}}; - } +#----------------------------------------------------------------------- +# Determine which shapes to create for each (font, style) combination; +# return a list of (font, style, shape) tuples +#----------------------------------------------------------------------- +sub expand_shapes { + return map { my ($font, $style) = @{$_}{qw(font style)}; + map { { font => $font, style => $style, shape => $_ } } + grep { has_reqd($font, $SHAPE{$_}) } + @{$STYLE{$style}{shapes}}; + } + @_; +} - ENCODING: - for my $enc_ref (@encodings) { - my ($enc_name, $enc_code) = @{$enc_ref}; - $enc_name =~ s/\A (ly1|ot1|t1) \z/fontools_$1/xms; - - # Create unique name for this font - my $fontname = join '-', - $fontinfo{name}, - lc $figure_style, - $SHAPE{$shape}{name}, - $enc_code, - ; - $fontname =~ s/[-]{2,}/-/xmsg; - - # Create the command line for otftotfm - my $command - = join ' ', - 'otftotfm', - "--encoding=$enc_name", - ($ARGV{manual} ? '--pl' : '--automatic'), - "--map-file=$fontinfo{family}.map --no-updmap", - ($filename =~ m/[.]ttf\z/xms - ? '--no-type1' - : ''), - ($CODING_SCHEME{$enc_name} - ? "--coding-scheme=" - . "\"$CODING_SCHEME{$enc_name}\"" - : ''), - (map { "--feature=$_" } @features), - # if there's no 'liga' feature, - # add ligkern commands for common ligatures - ((grep { $_ eq 'liga' } @features) - ? '' - : '--ligkern="f i =: fi" ' - . '--ligkern="f l =: fl" ' - . '--ligkern="f f =: ff" ' - . '--ligkern="ff i =: ffi" ' - . '--ligkern="ff l =: ffl" '), - $FIGURE_STYLE{$figure_style}{extra}, - $SHAPE{$shape}{extra}, - $ARGV{extra}, - '"' . $filename . '"', - $fontname, - ; - - # Save the command and the necessary data for .fd files - push @{$commands{$fontinfo{family}}}, $command; - push @fd_data, - join '|', - $fontinfo{family}, - uc $enc_code, - $figure_style, - $FD_WEIGHT{$fontinfo{weight}} - . $FD_WIDTH{$fontinfo{width}} - || 'm', - $SHAPE{$shape}{code}{$basic}, - sprintf("%04.1f",$fontinfo{min}), - sprintf("%04.1f",$fontinfo{max}), - $fontname, - ; - - if ($ARGV{verbose}) { - printf " %-42s %4s/%s-%s/%s/%s\n", - $fontname, - uc $enc_code, - $fontinfo{family}, - $figure_style, - $FD_WEIGHT{$fontinfo{weight}} - .$FD_WIDTH{$fontinfo{width}} - || 'm', - $SHAPE{$shape}{code}{$basic}, - ; - } - } - } - } - } +#----------------------------------------------------------------------- +# Check if $font has (at least one of the) features mentioned in the +# 'reqd' subtable of $target +#----------------------------------------------------------------------- +sub has_reqd { + my ($font, $target) = @_; - # If parsing failed, flush STDOUT, print the error messages and die - if (defined $err_msg) { - close STDOUT; - die $err_msg . <<'END_GENERAL_PARSE_ERROR'; - - -I suspect your font family contains some unusual weights or widths. -You might try adding missing widths and weights to the tables -'%FD_WIDTH' and '%FD_WEIGHT' at the beginning of the source code; -otherwise, please send a bug report to <marc@penninga.info>. -END_GENERAL_PARSE_ERROR - } - - @fd_data = sort @fd_data; - - for my $fd_line (@fd_data) { - my @fd_line = split /[|]/, $fd_line; - $fd_line[5] += 0; - $fd_line[6] += 0; - $fd_line = \@fd_line; - } - - # Adjust size ranges - $fd_data[0][5] = ''; - for my $i (0 .. $#fd_data - 1) { - if (grep { $fd_data[$i][$_] ne $fd_data[$i + 1][$_] } 0 .. 4) { - $fd_data[$i][6] = $fd_data[$i + 1][5] = ''; - } - else { - $fd_data[$i][6] = $fd_data[$i + 1][5]; - } - } - $fd_data[-1][6] = ''; - - # Generate .fd files - my @fd_prev = ('') x 8; - my $FD; - for my $fd_line_ref (@fd_data) { - my @fd_line = @{$fd_line_ref}; - - my $safe = $fd_line[0]; - $safe =~ s/1/One/xmsg; - $safe =~ s/2/Two/xmsg; - $safe =~ s/3/Three/xmsg; - $safe =~ s/4/Four/xmsg; - $safe =~ s/5/Five/xmsg; - $safe =~ s/6/Six/xmsg; - $safe =~ s/7/Seven/xmsg; - $safe =~ s/8/Eight/xmsg; - $safe =~ s/9/Nine/xmsg; - $safe =~ s/0/Zero/xmsg; - - write_style_file($fd_line[0], $safe, @fd_data) - if $fd_line[0] ne $fd_prev[0]; - - if (grep { $fd_line[$_] ne $fd_prev[$_] } 0 .. 2) { - end_fd_file($FD) if $fd_prev[0]; - $FD = start_fd_file(@fd_line[0 .. 2], $safe); - } - - if (grep { $fd_line[$_] ne $fd_prev[$_] } 0 .. 4) { - # Start new fontshape - if (not grep { $fd_line[$_] ne $fd_prev[$_] } 0 .. 2) { - print {$FD} "}{}\n\n"; + return 0 unless defined $target; + return 1 unless @{$target->{reqd}}; + return grep { $font->{feature}{$_} } @{$target->{reqd}}; +} + +#----------------------------------------------------------------------- +# Determine which encodings to use for each (font, style, shape) combi; +# return a list of (font, style, shape, encoding) tuples +#----------------------------------------------------------------------- +sub expand_encodings { + return + map { my ($font, $style, $shape) = @{$_}{qw(font style shape)}; + my @encodings + = $shape eq 'textcomp' ? (['fontools_ts1', 'ts1']) + : $style eq 'Orn' ? ([Fontinfo::get_orn($font), 'u']) + : map { [lc $_, lc $_] } @{$ARGV{encoding}} + ; + map { { font => $font, + style => $style, + shape => $shape, + encoding => $_, + } + } + @encodings; } - printf {$FD} "\\DeclareFontShape{%s}{%s-%s}{%s}{%s}{\n", - @fd_line[1, 0, 2, 3, 4]; + @_; +} + +#----------------------------------------------------------------------- +# Add some finishing touches to the work list +#----------------------------------------------------------------------- +sub cleanup { + my @worklist = @_; + + for my $item (@worklist) { + my ($font, $style, $shape, $encoding) + = @{$item}{qw(font style shape encoding)}; + + # generate unique name for this font + $item->{fontname} = join '-', grep { $_ } $font->{name}, + lc $style, + lc $SHAPE{$shape}{name}, + lc $encoding->[1]; + + # look up NFSS code for font's shape + $item->{fdshape} + = $SHAPE{$shape}{code}{$font->{basicshape}}; + + # compile list of OpenType features to use with this font + my %feature = map { ($_ => 1) } + grep { $font->{feature}{$_} } + ( @{$STYLE{$style}{reqd}}, + @{$STYLE{$style}{nice}}, + @{$SHAPE{$shape}{reqd}}, + @{$SHAPE{$shape}{nice}}, + ); + if ($feature{lnum} && $feature{onum}) { + delete $feature{lnum}; } - - # Write fontshape entry - printf {$FD} " %s \\%s\@\@scale %s\n", - sprintf("%5s-%-5s", '<' . $fd_line[5], $fd_line[6] . '>'), - $safe, - $fd_line[7], - ; - - @fd_prev = @fd_line; + $item->{features} = [ sort keys %feature ]; + + # add finishing touches to name and NFSS code of encoding + $item->{encoding}[0] =~ s/\A (ot1|t1|ly1) \z/fontools_$1/xms; + $item->{encoding}[1] = uc $item->{encoding}[1]; } - - end_fd_file($FD) if $fd_prev[0]; - # Print or execute the generated commands + return @worklist; +} + +#----------------------------------------------------------------------- +# Generate all otftotfm commands, and either save or execute them +#----------------------------------------------------------------------- +sub make_commands { + my @worklist = @_; + + my @commands = map { make_cmdline($_) } @worklist; + + # make sure the last command *does* call updmap + $commands[-1] =~ s/--no-updmap//xms; + if ($ARGV{manual}) { - while (my ($fam, $cmds_ref) = each %commands) { - open my $BAT, '>', "$fam.bat" - or die "ERROR: can't create '$fam.bat' - $!"; - print {$BAT} "$_\n" for @{$cmds_ref}; - close $BAT; - } + open my $BAT, '>', 'autoinst.bat' + or die "[ERROR] Can't create 'autoinst.bat': $!"; + print {$BAT} "$_\n" for @commands; + close $BAT; } else { - # Remove the --no-updmap option from the last command for each family - map { $_->[-1] =~ s/--no-updmap//xms } values %commands; - - for my $cmds_ref (values %commands) { - for my $cmd (@{$cmds_ref}) { - print "$cmd\n"; - system $cmd and warn <<'END_OTFTOTFM_WARNING'; - -WARNING: 'otftotfm' finished with a non-zero return code; - I'm afraid something went wrong! - -END_OTFTOTFM_WARNING - } + if (grep { system $_ } @commands) { + warn "[WARNING] 'otftotfm' returned non-zero; something's wrong!"; } } + + return; +} + +# The official names for various coding schemes +my %SCHEME = ( + fontools_ly1 => 'TEX TYPEWRITER AND WINDOWS ANSI', + fontools_t1 => 'EXTENDED TEX FONT ENCODING - LATIN', + fontools_ot1 => 'TEX TEXT', + fontools_ts1 => 'TEX TEXT COMPANION SYMBOLS 1---TS1', +); + +#----------------------------------------------------------------------- +# Generate a command line for otftotfm +#----------------------------------------------------------------------- +sub make_cmdline { + my $item = shift; + + return join ' ', 'otftotfm', + ($ARGV{manual} ? '--pl' : '--automatic'), + "--encoding=$item->{encoding}[0]", + set_targetdirs($item->{font}{family}), + '--no-updmap', + ($item->{font}{filename} =~ m/[.]ttf\z/xms + ? '--no-type1' + : ''), + ($SCHEME{$item->{encoding}[0]} + ? qq(--coding-scheme="$SCHEME{$item->{encoding}[0]}") + : ''), + (map { "--feature=$_" } @{$item->{features}}), + ((grep { $_ eq 'liga' } @{$item->{features}}) + ? '' + : ( '--ligkern="f i =: fi"', + '--ligkern="f l =: fl"', + '--ligkern="f f =: ff"', + '--ligkern="ff i =: ffi"', + '--ligkern="ff l =: ffl"' )), + $STYLE{$item->{style}}{extra}, + $SHAPE{$item->{shape}}{extra}, + $ARGV{extra}, + qq("$item->{font}{filename}"), + $item->{fontname}, + ; +} + +#----------------------------------------------------------------------- +# Return a string with all "directory" options for otftotfm set +#----------------------------------------------------------------------- +sub set_targetdirs { + my $family = shift; + + my %dir = map { ($_ => File::Spec->catdir( + $ARGV{target}, 'fonts', $_, 'lcdftools', $family)) + } + qw(tfm vf pl vpl type1 truetype type42); + + $dir{$_} = File::Spec->catdir( + $ARGV{target}, 'fonts', $_, 'dvips', 'lcdftools') + for qw(enc map); + + File::Path::make_path(values %dir); + + my $result = join ' ', map { "--${_}-directory=$dir{$_}" } + qw(tfm vf pl vpl type1 truetype type42); + $result .= " --encoding-directory=$dir{enc} --map-file=" + . File::Spec->catfile($dir{map}, "${family}.map"); + + return $result; } -# ------------------------------------------------------------------------ +############################################################################ + + +package ARGV; + +my $USAGE =<<'END_USAGE'; + +'autoinst' is a wrapper around Eddie Kohler's TypeTools +(http://www.lcdf.org/type/), for installing OpenType fonts in LaTeX. + +Usage: autoinst [options] font[s] + +Possible options: + -encoding=ENC[,ENC]* Specify text encoding(s) (default: OT1,T1,LY1) + + -(no)ts1 Toggle creation of TS1 fonts + -(no)smallcaps Toggle creation of smallcaps shape + -(no)swash Toggle creation of swash shape + -(no)titling Toggle creation of titling shape + -(no)superiors Toggle creation of fonts with superior characters + -(no)inferiors Toggle creation of fonts with inferior characters + -(no)ornaments Toggle creation of ornament fonts + -(no)fractions Toggle creation of fonts with digits for fractions + + -sanserif Install font as sanserif font + -typewriter Install font as typewriter font + -extra="TEXT" Add TEXT to the command line for 'otftotfm' + -target="DIRECTORY" Install files into specified TEXMF tree + -manual Manual mode (see documentation) + + -(no)figurekern Keep or remove kerns between tabular figures + + -help Print this text + -verbose Make some noise + + font[s] The fonts (either .otf or .ttf) to install. + +Please report any bugs or suggestions to <marcpenninga@gmail.com>. +END_USAGE + +# Default values for the command-line arguments +%ARGV = ( + encoding => 'OT1,T1,LY1', + textcomp => '2', # 0 = no, 1 = yes, 2 = (enc eq 'T1' ? yes : no) + smallcaps => '1', # 0 = no, 1 = yes + swash => '1', # 0 = no, 1 = yes + titling => '1', # 0 = no, 1 = yes + superiors => '1', # 0 = no, 1 = yes + inferiors => '0', # 0 = no, 1 = yes + ornaments => '1', # 0 = no, 1 = yes + fractions => '0', # 0 = no, 1 = yes + nfss => 'rm', + extra => '', + target => '', + manual => '0', # 0 = no, 1 = yes + verbose => '0', # 0 = no, 1 = yes + figurekern => '1', # 0 = no, 1 = yes +); + +#----------------------------------------------------------------------- +# Process command-line arguments +#----------------------------------------------------------------------- sub parse_options { my $cmdline = "$0 " . join ' ', @ARGV; - - GetOptions( - 'help' => sub { print $USAGE; exit }, - 'encoding=s' => \$ARGV{encoding}, - 'ts1!' => \$ARGV{textcomp}, - 'manual' => \$ARGV{manual}, - 'verbose' => \$ARGV{verbose}, - 'extra=s' => \$ARGV{extra}, - 'sanserif' => sub { $ARGV{nfss} = 'sf' }, - 'typewriter' => sub { $ARGV{nfss} = 'tt' }, - 'smallcaps!' => \$ARGV{smallcaps}, - 'swash!' => \$ARGV{swash}, - 'titling!' => \$ARGV{titling}, - 'superiors!' => \$ARGV{superiors}, - 'inferiors!' => \$ARGV{inferiors}, - 'ornaments!' => \$ARGV{ornaments}, - 'fractions!' => \$ARGV{fractions}, + + Getopt::Long::GetOptions( + 'help|?' => sub { print $USAGE; exit; }, + 'encoding=s' => \$ARGV{encoding}, + 'ts1!' => \$ARGV{textcomp}, + 'smallcaps!' => \$ARGV{smallcaps}, + 'swash!' => \$ARGV{swash}, + 'titling!' => \$ARGV{titling}, + 'superiors!' => \$ARGV{superiors}, + 'inferiors!' => \$ARGV{inferiors}, + 'ornaments!' => \$ARGV{ornaments}, + 'fractions!' => \$ARGV{fractions}, + 'sanserif' => sub { $ARGV{nfss} = 'sf' }, + 'typewriter' => sub { $ARGV{nfss} = 'tt' }, + 'extra=s' => \$ARGV{extra}, + 'target=s' => \$ARGV{target}, + 'manual' => \$ARGV{manual}, + 'figurekern!' => \$ARGV{figurekern}, + 'verbose' => \$ARGV{verbose}, ) or die "$USAGE"; @@ -605,33 +597,57 @@ sub parse_options { if (!$ARGV{swash} ) { delete $SHAPE{swash} } if (!$ARGV{titling} ) { delete $SHAPE{titling} } - if (!$ARGV{superiors}) { delete $FIGURE_STYLE{Sup} } - if (!$ARGV{inferiors}) { delete $FIGURE_STYLE{Inf} } - if (!$ARGV{ornaments}) { delete $FIGURE_STYLE{Orn} } - if (!$ARGV{fractions}) { delete @FIGURE_STYLE{qw(Numr Dnom)} } - + if (!$ARGV{superiors}) { delete $STYLE{Sup} } + if (!$ARGV{inferiors}) { delete $STYLE{Inf} } + if (!$ARGV{ornaments}) { delete $STYLE{Orn} } + if (!$ARGV{fractions}) { delete @STYLE{qw(Numr Dnom)} } + $ARGV{encoding} =~ s/\s+//xmsg; my @textencodings = grep { $_ ne 'TS1' } - map { uc } + map { uc } split /,/, $ARGV{encoding}; $ARGV{encoding} = \@textencodings; # TS1-encoded fonts are generated if: - # - text encoding is T1 and the user didn't turn off TS1, or - # - the user explicitly asked for TS1 - if ( - !( (grep { $_ eq 'T1' } @{$ARGV{encoding}} and $ARGV{textcomp}) - or $ARGV{textcomp} == 1 - )) { + # - the user explicitly asked for TS1, or + # - the text encodings contain T1 and the user didn't turn off TS1 + unless ( (grep { $_ eq 'T1' } @{$ARGV{encoding}} and $ARGV{textcomp}) + or $ARGV{textcomp} == 1) + { delete $SHAPE{textcomp}; } - + + if ($ARGV{manual}) { + warn "[WARNING] option '--target' overridden by '--manual'!" + if $ARGV{target}; + $ARGV{target} = File::Spec->curdir(); + } + elsif (not $ARGV{target}) { + my @dirs = grep { -w $_ } + map { split m/:/xms, substr $_, 0, -1 } + ( `kpsewhich --expand-path='\$TEXMFLOCAL'`, + `kpsewhich --expand-path='\$TEXMFHOME'`, ); + $ARGV{target} = $dirs[0] || File::Spec->curdir(); + } + + if (!$ARGV{figurekern}) { + my @digits = qw(zero one two three four five six seven eight nine); + my $tkern + = join ' ', map { my $left = $_; + map { qq(--ligkern="$left {} $_") } @digits + } + @digits; + + $STYLE{TLF}{extra} = $tkern; + $STYLE{TOsF}{extra} = $tkern; + } + if ($ARGV{verbose}) { print <<"END_ARGUMENTS"; $cmdline - + I'm using the following options: encoding(s): @{[ join ', ', @{$ARGV{encoding}} ]} @@ -639,279 +655,379 @@ I'm using the following options: : $ARGV{nfss} eq 'sf' ? '(sanserif)' : $ARGV{nfss} eq 'tt' ? '(typewriter)' : '(unknown)' - ]} + ]} + + (no)ts1: @{[ $SHAPE{textcomp} ? 'ts1' : 'nots1' ]} + (no)smallcaps: @{[ $ARGV{smallcaps} ? 'smallcaps' : 'nosmallcaps' ]} + (no)swash: @{[ $ARGV{swash} ? 'swash' : 'noswash' ]} + (no)titling: @{[ $ARGV{titling} ? 'titling' : 'notitling' ]} + (no)superiors: @{[ $ARGV{superiors} ? 'superiors' : 'nosuperiors' ]} + (no)inferiors: @{[ $ARGV{inferiors} ? 'inferiors' : 'noinferiors' ]} + (no)ornaments: @{[ $ARGV{ornaments} ? 'ornaments' : 'noornaments' ]} + (no)fractions: @{[ $ARGV{fractions} ? 'fractions' : 'nofractions' ]} - (no)ts1: @{[ $SHAPE{textcomp} ? 'ts1' : 'nots1' ]} - (no)smallcaps: @{[ $ARGV{smallcaps} ? 'smallcaps' : 'nosmallcaps' ]} - (no)swash: @{[ $ARGV{swash} ? 'swash' : 'noswash' ]} - (no)titling: @{[ $ARGV{titling} ? 'titling' : 'notitling' ]} - (no)superiors: @{[ $ARGV{superiors} ? 'superiors' : 'nosuperiors' ]} - (no)inferiors: @{[ $ARGV{inferiors} ? 'inferiors' : 'noinferiors' ]} - (no)ornaments: @{[ $ARGV{ornaments} ? 'ornaments' : 'noornaments' ]} - (no)fractions: @{[ $ARGV{fractions} ? 'fractions' : 'nofractions' ]} + verbosity: @{[ $ARGV{verbose} ? 'verbose' : 'quiet' ]} + target: $ARGV{target} + auto/manual: @{[ $ARGV{manual} ? 'manual' : 'automatic' ]} extra: @{[ $ARGV{extra} || 'empty' ]} - auto/manual: @{[ $ARGV{manual} ? 'manual' : 'automatic' ]} - verbosity: @{[ $ARGV{verbose} ? 'verbose' : 'silent' ]} + figurekern: @{[ $ARGV{figurekern} ? 'keep' : 'discard' ]} END_ARGUMENTS } } -# ------------------------------------------------------------------------ - -sub read_font_info { - my ($fontfile) = @_; - - my %info = (); - - # Read some general info about the font - open my $OTFINFO, '-|', "otfinfo --info \"$fontfile\"" - or die "ERROR: 'otfinfo --info \"$fontfile\"' failed"; - - LINE: - for my $line (<$OTFINFO>) { - my ($key, $val) = $line =~ m/([^:]+) :\s* ([^\n]+)/xms - or next LINE; - $val =~ s/[^-\w]//xmsg; - $info{$key} = $val; - } - close $OTFINFO; - if ($info{Family} =~ m/\A (.+ (?: OT | Pro))/xms) { - $info{Family} = $1; +############################################################################ + + +package Fontinfo; + +#----------------------------------------------------------------------- +# Return ref to hash with all relevant info about this font +#----------------------------------------------------------------------- +sub parse_fontinfo { + my ($filename) = @_; + + my $info = { + filename => $filename, + width => 'regular', + weight => 'regular', + shape => 'roman', + minsize => 0, + maxsize => 0, + }; + + parse_basicinfo($info); + parse_sizeinfo($info); + parse_features($info); + + if ($ARGV{verbose}) { + print <<"END_FONTINFO"; +$info->{filename} + Name: $info->{name} + Family: $info->{family} + Subfamily: $info->{subfamily} + Width: $info->{width} + Weight: $info->{weight} + Shape: $info->{shape} + Size: $info->{minsize}-$info->{maxsize} + Features: @{[ join ', ', sort keys %{$info->{feature}} ]} + +END_FONTINFO } - - $info{'Full name'} =~ s/$info{Family}//xmsg; - $info{'Full name'} = lc $info{'Full name'}; - $info{Family} =~ s/\A (?: Adobe | ITC ) | LT | MT//xmsg; - - # Set default - my %fontinfo = ( - filename => $fontfile, - name => $info{'PostScript name'}, - family => $info{Family}, - width => 'regular', - weight => 'regular', - shape => 'roman', - min => 0, - max => 0, - features => {}, - ); - - # Try to match width, weight and (basic) shape - WIDTH: - for my $width (map { quotemeta } - reverse sort - { length($a) <=> length($b) || $a cmp $b } - keys %FD_WIDTH) - { - if ($info{'Full name'} =~ s/$width//xmsi) { - $fontinfo{width} = $width; - last WIDTH; + + return $info; +} + +# table for converting digits in font names to text (safer for LaTeX) +my @DIGITS = qw(Zero One Two Three Four Five Six Seven Eight Nine); + +#----------------------------------------------------------------------- +# Get some basic info (family, weight, width, shape) about this font +#----------------------------------------------------------------------- +sub parse_basicinfo { + my $info = shift; + + open my $otfinfo, '-|', qq(otfinfo --info "$info->{filename}") + or die "[ERROR] 'otfinfo --info $info->{filename}' failed"; + my %data = map { my ($k,$v) = m/\A\s* ([^:]+?) \s*:\s* ([^\r\n]+)/xms; + $k =~ s/\s+//xmsg; + $v =~ s/\s+//xmsg; + (lc $k => $v); + } + grep { m/\A\s* [^:]+? \s*:\s* [^\r\n]+/xms } <$otfinfo>; + close $otfinfo; + + $data{family} = $data{preferredfamily} || $data{family}; + $data{subfamily} = $data{preferredsubfamily} || $data{subfamily}; + $data{fullname} =~ s/\A$data{family}//xms; + $data{fullname} = lc $data{fullname}; + $data{family} =~ s/\A(?: Adobe | ITC | LT | MT)//xms; + $data{family} =~ s/(\d)/$DIGITS[$1]/xmsge; + + for my $width (mqrs(keys %FD_WIDTH)) { + if ($data{fullname} =~ s/${width}//xmsi) { + $info->{width} = $width; + last; } } - - WEIGHT: - for my $weight (map { quotemeta } - reverse sort - { length($a) <=> length($b) || $a cmp $b } - keys %FD_WEIGHT) - { - if ($info{'Full name'} =~ s/$weight//xmsi) { - $fontinfo{weight} = $weight; - last WEIGHT; + + for my $weight (mqrs(keys %FD_WEIGHT)) { + if ($data{fullname} =~ s/${weight}//xmsi) { + $info->{weight} = $weight; + last; } } - SHAPE: - for my $shape (map { quotemeta } - reverse sort - { length($a) <=> length($b) || $a cmp $b } - keys %FD_SHAPE) - { - if ($info{'Full name'} =~ s/$shape//xmsi) { - $fontinfo{shape} = $shape; - last SHAPE; + + for my $shape (mqrs(keys %FD_SHAPE)) { + if ($data{fullname} =~ s/${shape}//xmsi) { + $info->{shape} = $shape; + last; } } - - # Read optical size info - open $OTFINFO, '-|',"otfinfo --optical-size \"$fontfile\"" - or die "ERROR: 'otfinfo --optical-size \"$fontfile\"' failed"; - if (my ($fm, $to) - = <$OTFINFO> =~ m/ - [(] - ( [\d.]+ ) \s* pt, \s* - ( [\d.]+ ) \s* pt \s* - []] - /xms) { - # Work around some known bugs - if ($fontinfo{name} eq 'GaramondPremrPro-It' - && $fm == 6 - && $to == 8.9) { - @fontinfo{qw(min max)} = (8.9, 14.9); - } - elsif ($fontinfo{family} eq 'KeplerStd' - && $info{Subfamily} =~ m/Caption/xms - && $fm == 8.9 - && $to == 13.9) { - @fontinfo{qw(min max)} = (6, 8.9); - } - elsif ($fontinfo{family} eq 'KeplerStd' - && $info{Subfamily} =~ m/Subhead/xms - && $fm == 8.9 - && $to == 13.9) { - @fontinfo{qw(min max)} = (13.9, 23); - } - elsif ($fontinfo{family} eq 'KeplerStd' - && $info{Subfamily} =~ m/Display/xms - && $fm == 8.9 - && $to == 13.9) { - @fontinfo{qw(min max)} = (23, 72); - } - else { - @fontinfo{qw(min max)} = ($fm, $to); + + $data{subfamily} =~ s/$info->{width}//xmsi; + $data{subfamily} =~ s/$info->{weight}//xmsi; + $data{subfamily} =~ s/$info->{shape}//xmsi; + + $info->{name} = $data{postscriptname}; + $info->{family} = $data{family}; + $info->{subfamily} = $data{subfamily}; + + $info->{basicshape} = $FD_SHAPE{$info->{shape}}; + $info->{fdseries} + = ($FD_WEIGHT{$info->{weight}} . $FD_WIDTH{$info->{width}}) || 'm'; + + return $info; +} + +#----------------------------------------------------------------------- +# When matching against data, try longer strings before shorter ones +#----------------------------------------------------------------------- +sub mqrs { + return map { quotemeta } reverse sort { length($a) <=> length($b) } @_; +} + +#----------------------------------------------------------------------- +# Get all features this font supports +#----------------------------------------------------------------------- +sub parse_features { + my $info = shift; + + open my $otfinfo, '-|', qq(otfinfo --features "$info->{filename}") + or die "[ERROR] 'otfinfo --features $info->{filename}' failed"; + %{$info->{feature}} = map { (substr($_, 0, 4) => 1) } <$otfinfo>; + close $otfinfo; + + open $otfinfo, '-|', qq(otfinfo --tables "$info->{filename}") + or die "[ERROR] 'otfinfo --tables $info->{filename}' failed"; + $info->{feature}{kern} = 1 if grep { m/\d+ \s+ kern/xms } <$otfinfo>; + close $otfinfo; + + return $info; +} + +#----------------------------------------------------------------------- +# Get the optical sizes for this font +#----------------------------------------------------------------------- +sub parse_sizeinfo { + my $info = shift; + + open my $otfinfo, '-|', qq(otfinfo --optical-size "$info->{filename}") + or die "[ERROR] 'otfinfo --optical-size $info->{filename}' failed"; + + if (my ($minsize, $maxsize) = <$otfinfo> =~ m/[(] ([\d.]+) \s* pt, \s* + ([\d.]+) \s* pt \s* []]/xms ) + { + # fix some known bugs + if ($info->{name} eq 'GaramondPremrPro-It' + && $minsize == 6 && $maxsize == 8.9) + { + ($minsize, $maxsize) = (8.9, 14.9); } - } - close $OTFINFO; - - # See what features this font provides - open $OTFINFO, '-|',"otfinfo --features \"$fontfile\"" - or die "ERROR: 'otfinfo --features \"$fontfile\"' failed"; - for my $line (<$OTFINFO>) { - if ($line =~ m/\A (\w{4}) \s+/xms) { - $fontinfo{features}{$1} = 1; + elsif ($info->{family} eq 'KeplerStd' + && $info->{subfamily} =~ m/Caption/xms + && $minsize == 8.9 && $maxsize == 13.9) + { + ($minsize, $maxsize) = (6, 8.9); } - } - close $OTFINFO; - - # Check if there's a "kern" table - open $OTFINFO, '-|',"otfinfo --tables \"$fontfile\"" - or die "ERROR: 'otfinfo --tables \"$fontfile\"' failed"; - for my $line (<$OTFINFO>) { - if ($line =~ m/\d+ \s+ (\w{4}) \s+/xms && $1 eq 'kern') { - $fontinfo{features}{kern} = 1; - last; + elsif ($info->{family} eq 'KeplerStd' + && $info->{subfamily} =~ m/Subhead/xms + && $minsize == 8.9 && $maxsize == 13.9) + { + ($minsize, $maxsize) = (13.9, 23); } - } - close $OTFINFO; - - if ($ARGV{verbose}) { - print <<"END_FONT_INFO"; - -$fontfile: - Family $fontinfo{family} - Width $fontinfo{width} - Weight $fontinfo{weight} - Shape $fontinfo{shape} - Size @{[ $fontinfo{min} || '']}-@{[ $fontinfo{max} || '' ]} -END_FONT_INFO - - my @features = sort keys %{$fontinfo{features}}; - my $prefix = ' Features '; - while (@features) { - print $prefix, join(' ', splice @features, 0, 10), "\n"; - $prefix = ' ' x length $prefix; + elsif ($info->{family} eq 'KeplerStd' + && $info->{subfamily} =~ m/Display/xms + && $minsize == 8.9 && $maxsize == 13.9) + { + ($minsize, $maxsize) = (23, 72); } - print "\n"; + + @{$info}{qw(minsize maxsize)} = ($minsize, $maxsize); } - - return %fontinfo; + close $otfinfo; + + return $info; } -=begin Comment +# Error messages, used in assert_unique() +my $WARN_PARSE =<<'END_WARN_PARSE'; +[WARNING] I failed to parse all fonts in a unique way, so I will split + your font family into multiple subfamilies and try again: - Ornament glyph names vary across fonts, so we generate font-specific - encoding vectors. - This is skipped if a file `<family>_orn.enc' is found in the current - directory, so the user can provide her own vector if she wants to. + %s -=end Comment + Please check the output! -=cut +END_WARN_PARSE -sub make_ornament_encoding { - my (%fontinfo) = @_; +my $ERR_PARSE =<<'END_ERR_PARSE'; +[ERROR] I failed to parse all fonts in a unique way; + presumably some fonts have unusual widths, weights or shapes. - my $fontfile = $fontinfo{filename}; - my $enc_name = $fontinfo{family} . '_orn'; - - if (not -e "$enc_name.enc") { + Try one of the following: + - Run 'autoinst' on a smaller set of fonts, + omitting the ones that weren't parsed correctly; + - Add the missing widths, weights or shapes to the tables + '%FD_WIDTH', '%FD_WEIGHT' or '%FD_SHAPE' near the top + of the source code; + + Please also send a bug report to the author. + +END_ERR_PARSE + +my $ERR_DETAIL =<<'END_ERR_DETAIL'; +[ERROR] I've parsed both %s + and %s as + + Family: %s + Width: %s + Weight: %s + Shape: %s + Size: %s-%s + +END_ERR_DETAIL +#----------------------------------------------------------------------- +# Assert all font infos are unique +#----------------------------------------------------------------------- +sub assert_unique { + my @fonts = @_; + + # These attributes should uniquely identify each font + my @attributes = qw(family width weight shape minsize maxsize); + + ATTEMPT: + for my $attempt (1 .. 2) { + my (%seen, $err_details); + for my $font (@fonts) { + my $key + = join "\x00", + @{$font}{ @attributes }; + + if ($seen{$key}) { + $err_details .= sprintf $ERR_DETAIL, + $seen{$key}{filename}, + $font->{filename}, + @{$font}{ @attributes }; + } + else { + $seen{$key} = $font; + } + } + + # If the font infos aren't unique, append 'Subfamily' to 'Family' + # and try again + if ($err_details) { + if ($attempt == 1) { + $err_details =~ s/\[ERROR\]/[WARNING]/xmsg; + warn $err_details; + + for my $font (@fonts) { + $font->{family} .= $font->{subfamily}; + } + + my @subfamilies + = sort keys %{{ map { ($_->{family} => 1) } @fonts }}; + warn sprintf $WARN_PARSE, join ', ', @subfamilies; + + next ATTEMPT; + } + else { + die $err_details, $ERR_PARSE; + } + } + + last ATTEMPT; + } + + return 1; +} + +#----------------------------------------------------------------------- +# Generate (font-specific) encoding vector for ornament glyphs +#----------------------------------------------------------------------- +sub get_orn { + my ($font) = @_; + + my $fontfile = $font->{filename}; + my $enc_name = $font->{family} . '_orn'; + + if (not -e "$enc_name.enc") { # Default ornament names: 'orn.' plus three digits my @encoding = map { sprintf "orn.%03d", $_ } 1 .. 256; - - open my $OTFINFO, '-|', "otfinfo --glyphs \"$fontfile\"" - or die "ERROR: 'otfinfo --glyphs \"$fontfile\"' failed"; + + open my $OTFINFO, '-|', qq(otfinfo --glyphs "$font->{filename}") + or die "[ERROR] 'otfinfo --glyphs $font->{filename}' failed"; chop(my @glyphnames = <$OTFINFO>); close $OTFINFO; # Test for some known alternative names (probably not exhaustive) - my @ornaments - = sort grep { m/\A (?:orn|u2022[.]|word[.]|hand|bullet[.]) | [.]orn \z/xms } + my @ornaments + = sort grep { m/\A (?: orn|u2022[.]|word[.]|hand|bullet[.]) + | [.]orn \z/xms + } @glyphnames; - - if (@ornaments > 256) { - @encoding = @ornaments[0 .. 255]; - } - else { - @encoding[0 .. $#ornaments] = @ornaments; - } - open my $ORNAMENTS, '>', "$enc_name.enc" - or die "ERROR: can't create '$enc_name.enc' - $!"; - - print {$ORNAMENTS} "/$fontinfo{family}OrnamentEncoding [\n"; - map { print {$ORNAMENTS} " /$_\n" } @encoding; - print {$ORNAMENTS} "] def\n"; - close $ORNAMENTS; + @encoding[0 .. $#ornaments] = @ornaments; + + open my $ORN, '>', "$enc_name.enc" + or die "[ERROR] Can't create '$enc_name.enc': $!"; + + print {$ORN} "/$font->{family}OrnamentEncoding [\n"; + map { print {$ORN} " /$_\n" } @encoding[0 .. 255]; + print {$ORN} "] def\n"; + close $ORN; } - + return $enc_name; } -# ------------------------------------------------------------------------ - -sub write_style_file { - my ($family, $safe, @fd_data) = @_; - - my (%seen_enc, %seen_style, %seen_series, %seen_shape); - - LINE: - for my $line_ref (@fd_data) { - my ($fam, $enc, $style, $series, $shape) = @{$line_ref}[0 .. 4]; - next LINE if $fam ne $family; - $seen_enc{$enc} = 1; - $seen_style{$style} = 1; - $seen_series{$series} = 1; - $seen_shape{$shape} = 1; - } - - open my $STYLE, '>', "$family.sty" - or die "ERROR: can't create '$family.sty' - $!"; - print {$STYLE} <<"END_STY_HEADER"; -%%Generayed by autoinst on $date + +############################################################################ + + +package LaTeX; + +#----------------------------------------------------------------------- +# Create a style file for LaTeX +#----------------------------------------------------------------------- +sub write_stylefile { + my ($fam, $data) = @_; + + my %seen = %{ get_keys($data) }; + + my $fn = sprintf "%s.sty", $fam; + my $dir = File::Spec->catdir($ARGV{target}, 'tex', 'latex', $fam); + File::Path::make_path($dir); + $fn = File::Spec->catfile($dir, $fn); + open my $STY, '>', $fn or die "[ERROR] Can't create '$fn': $!"; + + print {$STY} <<"END_STY_HEADER"; +%% Generated by autoinst on $TODAY %% \\NeedsTeXFormat{LaTeX2e} -\\ProvidesPackage{$family} - [$date (autoinst) Style file for $family.] - +\\ProvidesPackage{$fam} + [$TODAY (autoinst) Style file for $fam.] + END_STY_HEADER - - my $textenc = join ',', grep { $_ ne 'OT1' } @{$ARGV{encoding}}; - - print {$STYLE} "\\RequirePackage[$textenc]{fontenc}\n" if $textenc; - print {$STYLE} "\\RequirePackage{textcomp}\n" if $seen_enc{TS1}; - - print {$STYLE} <<'END_STY_FONTAXES_START'; + + my $enc = join ',', grep { $_ ne 'OT1' } @{$ARGV{encoding}}; + + print {$STY} "\\RequirePackage[$enc]{fontenc}\n" if $enc; + print {$STY} "\\RequirePackage{textcomp}\n" if $seen{TS1}; + + print {$STY} <<'END_STY_FONTAXES_START'; \IfFileExists{fontaxes.sty}{ \RequirePackage{fontaxes} END_STY_FONTAXES_START - if ($seen_shape{tl} || $seen_shape{tlit}) { - print {$STYLE} <<'END_STY_FONTAXES_TL'; + if ($seen{tl} or $seen{tlit}) { + print {$STY} <<'END_STY_FONTAXES_TL'; \providecommand{\tldefault}{tl} \DeclareRobustCommand\tlshape{\not@math@alphabet\tlshape\relax \fontsecondaryshape\tldefault\selectfont} @@ -919,82 +1035,79 @@ END_STY_FONTAXES_START \let\texttitling\texttl \fa@naming@exception{shape}{{n}{tl}}{tl} \fa@naming@exception{shape}{{it}{tl}}{tlit} - + END_STY_FONTAXES_TL } - if ($seen_shape{nw} || $seen_shape{sw}) { - print {$STYLE} <<'END_STY_FONTAXES_SW'; + if ($seen{nw} or $seen{sw}) { + print {$STY} <<'END_STY_FONTAXES_SW'; \DeclareRobustCommand\swshape{\not@math@alphabet\swshape\relax \fontprimaryshape\itdefault\fontsecondaryshape\swdefault\selectfont} \fa@naming@exception{shape}{{n}{sw}}{nw} \fa@naming@exception{shape}{{it}{sw}}{sw} - + END_STY_FONTAXES_SW } - if ($seen_style{Sup}) { - print {$STYLE} <<'END_STY_FONTAXES_SUP'; + if ($seen{Sup}) { + print {$STY} <<'END_STY_FONTAXES_SUP'; \fa@naming@exception{figures}{{superior}{proportional}}{Sup} \fa@naming@exception{figures}{{superior}{tabular}}{Sup} \def\sufigures{\@nomath\sufigures \fontfigurestyle{superior}\selectfont} \DeclareTextFontCommand{\textsu}{\sufigures} \let\textsuperior\textsu - + END_STY_FONTAXES_SUP } - if ($seen_style{Inf}) { - print {$STYLE} <<'END_STY_FONTAXES_INF'; + if ($seen{Inf}) { + print {$STY} <<'END_STY_FONTAXES_INF'; \fa@naming@exception{figures}{{inferior}{proportional}}{Inf} \fa@naming@exception{figures}{{inferior}{tabular}}{Inf} \def\infigures{\@nomath\infigures \fontfigurestyle{inferior}\selectfont} \DeclareTextFontCommand{\textin}{\infigures} \let\textinferior\textin - + END_STY_FONTAXES_INF } - if ($seen_style{Orn}) { - print {$STYLE} <<'END_STY_FONTAXES_ORN'; + if ($seen{Orn}) { + print {$STY} <<'END_STY_FONTAXES_ORN'; \fa@naming@exception{figures}{{ornament}{proportional}}{Orn} \fa@naming@exception{figures}{{ornament}{tabular}}{Orn} \def\ornaments{\@nomath\ornaments \fontencoding{U}\fontfigurestyle{ornament}\selectfont} \DeclareTextFontCommand{\textornaments}{\ornaments} \providecommand{\ornament}[1]{\textornaments{\char##1}} - + END_STY_FONTAXES_ORN } - if ($seen_style{Numr}) { - print {$STYLE} <<'END_STY_FONTAXES_NUMR'; + if ($seen{Numr}) { + print {$STY} <<'END_STY_FONTAXES_NUMR'; \fa@naming@exception{figures}{{numerators}{proportional}}{Numr} \fa@naming@exception{figures}{{numerators}{tabular}}{Numr} END_STY_FONTAXES_NUMR } - if ($seen_style{Dnom}) { - print {$STYLE} <<'END_STY_FONTAXES_DNOM'; + if ($seen{Dnom}) { + print {$STY} <<'END_STY_FONTAXES_DNOM'; \fa@naming@exception{figures}{{denominators}{proportional}}{Dnom} \fa@naming@exception{figures}{{denominators}{tabular}}{Dnom} END_STY_FONTAXES_DNOM } - print {$STYLE} <<'END_STY_FONTAXES_END'; -}{} - -END_STY_FONTAXES_END + print {$STY} "}{}\n\n"; - print {$STYLE} <<"END_STY_XKEYVAL"; + print {$STY} <<"END_STY_XKEYVAL"; \\IfFileExists{xkeyval.sty}{ - \\newcommand*{\\$safe\@scale}{1} + \\newcommand*{\\$fam\@scale}{1} \\RequirePackage{xkeyval} - \\DeclareOptionX{scaled}{\\renewcommand*{\\$safe\@scale}{##1}} + \\DeclareOptionX{scaled}{\\renewcommand*{\\$fam\@scale}{##1}} }{ \\let\\DeclareOptionX\\DeclareOption \\let\\ExecuteOptionsX\\ExecuteOptions @@ -1002,163 +1115,197 @@ END_STY_FONTAXES_END } END_STY_XKEYVAL - - if ($seen_style{LF} or $seen_style{TLF}) { - print {$STYLE} - "\\DeclareOptionX{lining}{\\edef\\$safe\@figurestyle{LF}}\n"; + + if ($seen{LF} or $seen{TLF}) { + print {$STY} + "\\DeclareOptionX{lining}{\\edef\\$fam\@figurestyle{LF}}\n"; } - if ($seen_style{OsF} or $seen_style{TOsF}) { - print {$STYLE} - "\\DeclareOptionX{oldstyle}{\\edef\\$safe\@figurestyle{OsF}}\n"; + if ($seen{OsF} or $seen{TOsF}) { + print {$STY} + "\\DeclareOptionX{oldstyle}{\\edef\\$fam\@figurestyle{OsF}}\n"; } - if ($seen_style{TLF} or $seen_style{TOsF}) { - print {$STYLE} - "\\DeclareOptionX{tabular}{\\edef\\$safe\@figurealign{T}}\n"; + if ($seen{TLF} or $seen{TOsF}) { + print {$STY} + "\\DeclareOptionX{tabular}{\\edef\\$fam\@figurealign{T}}\n"; } - if ($seen_style{LF} or $seen_style{OsF}) { - print {$STYLE} - "\\DeclareOptionX{proportional}{\\edef\\$safe\@figurealign{}}\n"; + if ($seen{LF} or $seen{OsF}) { + print {$STY} + "\\DeclareOptionX{proportional}{\\edef\\$fam\@figurealign{}}\n"; } - + my $defaults - = $seen_style{OsF} ? 'oldstyle,proportional' - : $seen_style{TOsF} ? 'oldstyle,tabular' - : $seen_style{LF} ? 'lining,proportional' - : $seen_style{TLF} ? 'lining,tabular' - : die "ERROR: encountered un unknown bug"; - + = $seen{OsF} ? 'oldstyle,proportional' + : $seen{TOsF} ? 'oldstyle,tabular' + : $seen{LF} ? 'lining,proportional' + : $seen{TLF} ? 'lining,tabular' + : die "[ERROR] Internal bug, please report!"; + my $default_bold; for my $series ( - qw(ultrablack ultrabold heavy extrablack black + qw(ultrablack ultrabold heavy extrablack black extrabold demibold semibold bold)) { - if ($seen_series{$FD_WEIGHT{$series}}) { - printf {$STYLE} + if ($seen{$FD_WEIGHT{$series}}) { + printf {$STY} "\\DeclareOptionX{%s}{\\renewcommand*{\\bfdefault}{%s}}\n", $series, $FD_WEIGHT{$series}; $default_bold = $series; } } $defaults .= ",$default_bold" if $default_bold; - + my $default_regular; for my $series ( qw(light medium regular)) { - if ($seen_series{$FD_WEIGHT{$series} || 'm'}) { - printf {$STYLE} + if ($seen{$FD_WEIGHT{$series} || 'm'}) { + printf {$STY} "\\DeclareOptionX{%s}{\\renewcommand*{\\mddefault}{%s}}\n", $series, $FD_WEIGHT{$series} || 'm'; $default_regular = $series; } } $defaults .= ",$default_regular" if $default_regular; - - print {$STYLE} <<"END_STYLE_REST"; + + print {$STY} <<"END_STYLE_REST"; \\ExecuteOptionsX{$defaults} \\ProcessOptionsX\\relax \\renewcommand* {\\$ARGV{nfss}default} - {$family-\\$safe\@figurealign\\$safe\@figurestyle} + {$fam-\\$fam\@figurealign\\$fam\@figurestyle} \\renewcommand*{\\familydefault}{\\$ARGV{nfss}default} \\endinput END_STYLE_REST - close $STYLE; + close $STY; + + return; } -# ------------------------------------------------------------------------ +#----------------------------------------------------------------------- +# Walk a nested dictionary, return lookup table with all keys +#----------------------------------------------------------------------- +sub get_keys { + my $dict = shift; + my $seen = shift || {}; + + while (my ($k, $v) = each %$dict) { + $seen->{$k} = 1; + get_keys($v, $seen) if ref $v eq 'HASH'; + } + + return $seen; +} + +#----------------------------------------------------------------------- +# Create a .fd file for LaTeX's NFSS +#----------------------------------------------------------------------- +sub write_fdfile { + my ($fam, $enc, $sty, $data) = @_; + + my $fn = sprintf "%s%s-%s.fd", $enc, $fam, $sty; + my $dir = File::Spec->catdir($ARGV{target}, 'tex', 'latex', $fam); + File::Path::make_path($dir); + $fn = File::Spec->catfile($dir, $fn); + open my $FD, '>', $fn or die "[ERROR] Can't create '$fn': $!"; -sub start_fd_file { - my ($fam, $enc, $fig, $safe) = @_; - - open my $FD, '>', "$enc$fam-$fig.fd" - or die "ERROR: can't create '$enc$fam-$fig.fd' - $!"; - print {$FD} <<"END_FD_HEADER"; -%%Generated by autoinst on $date +%% Generated by autoinst on $TODAY %% -\\ProvidesFile{$enc$fam-$fig.fd} - [$date (autoinst) Font definitions for $enc/$fam-$fig.] +\\ProvidesFile{${enc}${fam}-${sty}.fd} + [$TODAY (autoinst) Font definitions for ${enc}/${fam}-${sty}.] -\\expandafter\\ifx\\csname $safe\@scale\\endcsname\\relax - \\let\\$safe\@\@scale\\\@empty +\\expandafter\\ifx\\csname ${fam}\@scale\\endcsname\\relax + \\let\\${fam}\@\@scale\\\@empty \\else - \\edef\\$safe\@\@scale{s*[\\csname $safe\@scale\\endcsname]}% + \\edef\\${fam}\@\@scale{s*[\\csname ${fam}\@scale\\endcsname]}% \\fi - -\\DeclareFontFamily{$enc}{$fam-$fig}{} + +\\DeclareFontFamily{${enc}}{${fam}-${sty}}{} END_FD_HEADER - return $FD; + while (my ($series, $fdseries) = each %$data) { + while (my ($shape, $fdshape) = each %$fdseries) { + print {$FD} + "\\DeclareFontShape{$enc}{${fam}-${sty}}{$series}{$shape}{\n"; + my @items = sort { $a->[0] <=> $b->[0] } + @{$fdshape}; + $items[0][0] = $items[-1][1] = ''; + $items[$_][0] = $items[$_ - 1][1] for (1 .. $#items); + for my $item (@items) { + print {$FD} " <$item->[0]-$item->[1]>", + " \\${fam}\@\@scale $item->[2]\n"; + } + print {$FD} "}{}\n\n"; + } + } + print {$FD} "\\endinput\n"; + + close $FD; + + return; } -# ------------------------------------------------------------------------ -sub end_fd_file { - my ($FD) = @_; - - print {$FD} "}{}\n\n\\endinput\n"; - close $FD; -} +############################################################################ + +package main; -main() +main(); __END__ - pod2man --center="fontools" --date=`date +"%Y-%m-%d"` \ - --release="fontools" --section=1 autoinst autoinst.1 - - man -t ./autoinst.1 | ps2pdf - autoinst.pdf +############################################################################ + + + To create the documentation: + + pod2man --center="Marc Penninga" --release="fontools" --section=1 \ + autoinst - | groff -Tps -man - | ps2pdf - autoinst.pdf =pod =head1 NAME -autoinst - wrapper script around the F<LCDF TypeTools>, +autoinst - wrapper around the F<LCDF TypeTools>, for installing OpenType fonts in LaTeX. =head1 SYNOPSIS -autoinst [options] I<fontfile> [I<fontfile> ...] +B<autoinst> [I<options>] B<font(s)> =head1 DESCRIPTION -Eddie Kohler's F<TypeTools>, especially F<otftotfm>, are great tools for -installing OpenType fonts for use with LaTeX, but their use (even in -automatic mode) is quite complicated because it needs lots of long -command lines and doesn't generate the F<fd> and F<sty> files LaTeX needs. -B<autoinst> simplifies the font installation -process by generating and executing all commands for F<otftotfm> -and by creating all necessary F<fd> and F<sty> files. +Eddie Kohler's F<TypeTools>, especially F<otftotfm>, are superb tools +for installing OpenType fonts in LaTeX, but their use +(even in automatic mode) is complicated: they need many long +command lines and don't generate the F<fd> and F<sty> files LaTeX needs. +B<autoinst> simplifies the font installation process with F<otftotfm> +by generating and executing all command lines +and by creating and installing all F<fd> and F<sty> files. -All the user then needs -to do is move these files to a suitable location -(F<< $LOCALTEXMF/tex/latex/<Supplier>/<FontFamily>/ >> is the -official choice) and update TeX's filename database. - -Given a family of font files (in either F<.ttf> or F<.otf> format), +Given a family of font files (in either F<otf> or F<ttf> format), B<autoinst> will create several LaTeX font families: =over 2 -=over 2 +=over 3 -=item B<-> +=item - -Four text families (with lining and oldstyle figures, in tabular and +Four text families (with lining and oldstyle digits, in tabular and proportional variants), each with the following shapes: =over 2 -=over 4 +=over 6 =item I<n> @@ -1170,19 +1317,20 @@ Small caps =item I<nw> -`Upright swash'; usually normal text with some extra `oldstyle' ligatures, +"Upright swash"; usually normal text with some extra "oldstyle" ligatures, such as ct, sp and st. =item I<tl> -Titling shape. Meant for all-caps text only (even though it sometimes contains -lowercase glyphs as well), where letterspacing and the positioning of -punctuation characters have been adjusted to suit all-caps text. -This shape is generated only for the families with lining figures. +Titling shape. Meant for all-caps text only (even though it sometimes contains +lowercase glyphs as well), where letterspacing and the positioning of +punctuation characters have been adjusted to suit all-caps text. +This shape is generated only for the families with lining digits, since +all-caps text doesn't mix with old-style digits. =item I<it> -Italic or oblique text +Italic (or oblique) text =item I<scit> @@ -1200,17 +1348,17 @@ Italic titling =back -=item B<-> +=item - -For each text family: a family of TS1-encoded symbol fonts, +For each text family: a family of TS1-encoded symbol fonts, in roman and italic shapes. -=item B<-> +=item - Four families with superiors, inferiors, numerators and denominators, in roman and italic shapes. -=item B<-> +=item - An ornament family, in roman and italic shapes. @@ -1218,12 +1366,12 @@ An ornament family, in roman and italic shapes. =back -Of course, if the font doesn't contain oldstyle figures, small caps etc., -the corresponding shapes or families are not created; -furthermore, the creation of most families and shapes can be controlled by -command-line options (see below). +Of course, if the fonts don't contain oldstyle digits, small caps etc., +the corresponding shapes and families are not created. +Furthermore, the creation of most families and shapes can be controlled by +command-line options (see L</"COMMAND-LINE OPTIONS"> below). -The generated font families are named I<< <FontFamily>-<Suffix> >>, +The generated font families are named I<< <FontFamily>-<Suffix> >>, where I<< <Suffix> >> is one of =over 8 @@ -1246,13 +1394,13 @@ tabular oldstyle figures =item I<Sup> -superior characters (many fonts only have an incomplete set -of superiors: figures, some punctuation and the letters -I<abdeilmnorst>; normal forms will be used for the other characters) +superior characters (many fonts have only an incomplete set of superiors: +digits, punctuation and the letters I<abdeilmnorst>; +normal forms will be used for the other characters) =item I<Inf> -inferior characters; usually only figures and punctuation, +inferior characters; usually only digits and punctuation, normal forms for the other characters =item I<Orn> @@ -1269,29 +1417,30 @@ denominators =back -The generated fonts are named I<< <FontFile>-<suffix>-<shape>-<enc> >>, -where I<< <FontFile> >> is the name of the OpenType file, I<< <suffix> >> -is the same as above (but in lowercase), I<< <shape> >> is either empty, -`sc', `swash' or `titling', and I<< <enc> >> is the encoding. -A typical name in this scheme is F<MinionPro-Regular-osf-sc-ly1>. +The generated fonts are named I<< <FontName>-<suffix>-<shape>-<enc> >>, +where I<< <suffix> >> is the same as above (but in lowercase), +I<< <shape> >> is either empty, "sc", "swash" or "titling", +and I<< <enc> >> is the encoding. +A typical name in this scheme would be "MinionPro-Regular-osf-sc-ly1". =head2 On the choice of text encoding -By default, all text families use the LY1 encoding. This has been chosen -over T1 (Cork) because many OpenType fonts contain additional ligatures -such as fj and Th, and LY1 has a number of empty slots to accommodate these. -Different encodings can be selected using the B< --encoding> -command line option (see below). +By default, B<autoinst> generates text fonts with OT1, T1 and LY1 +encodings, and the generated style files use LY1 as the default text encoding. +LY1 has been chosen over T1 because it has some empty slots to accomodate +the additional ligatures and alternate glyphs provided by many OpenType fonts. +Different encodings can be selected using the I<-encoding> +command-line option (see L</"COMMAND-LINE OPTIONS"> below). -=head2 Using the fonts with LaTeX +=head2 Using the fonts in your LaTeX documents -B<autoinst> generates a style file for using the font in LaTeX documents, -named `<I<FontFamily>>.sty'. This style file also takes care of loading the +B<autoinst> generates a style file for using the font in LaTeX documents, +named F<< <FontFamily>.sty >>. This style file also takes care of loading the F<fontenc> and F<textcomp> packages, if necessary. -To use the font, simply put C<\usepackage{MinionPro}> -(or whatever the font is called) in the preamble of your document. +To use the font, simply put C<<< \usepackage{I<< <FontFamily> >>} >>> +in the preamble of your document. This style file defines a number of options: @@ -1299,268 +1448,321 @@ This style file defines a number of options: =item I<lining, oldstyle, tabular, proportional> -Choose which figures will be used for the text fonts. -The defaults are `oldstyle' and `proportional' (if available). +Choose which digits will be used for the text fonts. +The defaults are "oldstyle" and "proportional" (if available). =item I<ultrablack, ultrabold, heavy, extrablack, black, extrabold, demibold, semibold, bold> -Choose the weight that LaTeX will use for the `bold' weight +Choose the weight that LaTeX will use for the "bold" weight (i.e., the value of C<\bfdefault>). =item I<light, medium, regular> -Choose the weight that LaTeX will use for the `regular' weight +Choose the weight that LaTeX will use for the "regular" weight (i.e., the value of C<\mddefault>). =item I<< scaled=<scale> >> -Scale the font by a factor of I<< <scale> >>. +Scale the font by a factor of I<< <scale> >>. For example: to increase the size of the font by 5%, use the command -C<\usepackage[scaled=1.05]{MyriadPro}>. +C<<< \usepackage[scaled=1.05]{I<< <FontFamily> >>} >>>. This option is only available when the F<xkeyval> package is found in your TeX installation. =back -The style file will also try to load the F<fontaxes> package (part of -the MinionPro for LaTeX project), which gives easy access to various font -shapes and styles. This package can be downloaded from the project's homepage -(F<http://developer.berlios.de/projects/minionpro>) or directly through -the CVS web interface -(F<http://cvs.berlios.de/cgi-bin/viewcvs.cgi/minionpro/MinionPro/tex/>), -and is also available from CTAN as part of the archive F<metrics-base.zip> -(F<http://www.ctan.org/tex-archive/fonts/minionpro/metrics-base.zip>). - -Using the machinery set up by F<fontaxes>, the generated style file -also defines a few commands (which take the text to be typeset as argument) -and declarations (which don't take arguments, but affect all text up to +The style file will also try to load the F<fontaxes> package, +which gives easy access to various font shapes and styles. +It is available from CTAN +(F<http://www.ctan.org/tex-archive/macros/latex/contrib/fontaxes>). +Using the machinery set up by F<fontaxes>, the generated style file also +defines a number of commands (which take the text to be typeset as argument) +and declarations (which don't take arguments, but affect all text up to the end of the current group) of its own: DECLARATION COMMAND SHORT FORM OF COMMAND - + \tlshape \texttitling \texttl - \sufigures \textsuperior \textsu - \infigures \textinferior \textin - + \sufigures \textsuperior \textsu + \infigures \textinferior \textin + In addition, the C<\swshape> and C<\textsw> commands are redefined to place -swash on the secondary shape axis (F<fontaxes> places it on the primary -shape axis); this allows the use of `upright swash'. -Just saying C<\swshape> will still give normal (italic) swash, -but C<\swshape\upshape> results in upright swash. - -Note that there is no separate command for accessing the italic titling shape; -but these commands behave properly when nested, so C<\tlshape\itshape> gives -italic titling. -There are also no commands for accessing the numerator and denominator -fonts; these can be selected using F<fontaxes>' low-level commands, +swash on the secondary shape axis (F<fontaxes> places it on the primary +shape axis); this makes these commands behave properly when nested, so that +C<\swshape\upshape> will give upright swash. + +There are no commands for accessing the numerator and denominator +fonts; these can be selected using F<fontaxes>' standard commands, e.g., C<\fontfigurestyle{numerator}\selectfont>. -The style file also provides a command C<<< \ornament{I<< <number> >>} >>>, -where C<<< I<< <number> >> >>> is a number from 0 to the total number of -ornaments minus one. Ornaments are always typeset using the current family, +The style file also provides a command C<<< \ornament{I<< <number> >>} >>>, +where C<<< I<< <number> >> >>> is a number from 0 to the total number of +ornaments minus one. Ornaments are always typeset using the current family, series and shape. A list of all ornaments in a font can be created by -running LaTeX on the file F<nfssfont.tex> (part of a standard -LaTeX installation) and specifying the ornament font -(e.g., I<MinionPro-Regular-orn-u>). +running LaTeX on the file F<nfssfont.tex> (part of a standard +LaTeX installation) and supplying the name of the ornament font. + +To access the ornaments, B<autoinst> creates a font-specific encoding file +F<< <FontFamily>_orn.enc >>, but only if that file doesn't yet exist. +This means you can provide your own encoding vector, +e.g. if your fonts use non-standard glyph names for ornaments. These commands are only generated for shapes and number styles -that actually exist; no commands are generated for shapes and styles +that actually exist; no commands are generated for shapes and styles that don't exist, or whose generation has been turned off. - -This whole machinery builds on F<fontaxes>; if that package cannot be found, -the style file doesn't provide high-level access to the more `exotic' -font shapes and styles. In that case, you're limited to using the lower-level -commands from standard NFSS. +Please note that these commands are built on top of F<fontaxes>; +if that package cannot be found, you're limited to using the +lower-level commands from standard NFSS (C<\fontfamily>, C<\fontseries>, +C<\fontshape> etc.). =head2 Using multiple font families in one document -If you want to use several font families in one document, make sure -all fonts were installed using the same version of B<autoinst>. -B<autoinst> has seen some non-backward-compatible changes in the past, -and F<.sty> and F<.fd> files that were generated by different versions -of B<autoinst> may not be able to coexist peacefully. +If you want to use more than one font family in a document, be aware +that style files generated by versions of B<autoinst> older dan 2009 +are incompatible with those generated by newer versions. =head2 NFSS codes -In NFSS, weight and width are concatenated into a single `series' attribute. -B<autoinst> maps widths, weights and shapes to NFSS codes using -the following tables. These are based on the tables in Lehman's -F<Font Installation Guide>, but some changes had to be made to avoid -name clashes for font families with many different widths and weights -(such as Helvetica Neue). - - - WEIGHT WIDTH - - Thin t Ultra Condensed uc - Ultra Light ul Extra Condensed ec - Extra Light el Condensed c - Light l Semicondensed sc - Book [1] Regular [1] - Regular [1] Semiextended sx - Medium mb Extended x - Demibold db - Semibold sb - Bold b - Extra Bold eb SHAPES - Black a - Extra Black ea Roman n - Heavy h Italic it - Ultra ub Oblique it [2] - Ultra Bold ub RomanI n [3] - Ultra Black ua RomanII it [3] - +NFSS identifies fonts by a combination of family, series (weight plus width), +shape and size. +B<autoinst> parses the output of C<otfinfo --info> to determine +these parameters. When this fails +(e.g., because the font family contains unusual widths or weights), +B<autoinst> ends up with different fonts having the I<same> values +for the font parameters, which means that these fonts cannot be used in NFSS. +B<autoinst> will then split the font family into multiple subfamilies +(based on the font's "Subfamily" value) and try again. +(Since many font families overdo the "Subfamily" by making each font +a separate subfamily, this strategy is only used as a last resort.) + +If this proliferation of font families is unwanted, +either rerun B<autoinst> on a smaller set of fonts (omitting the ones that +failed to parse correctly) +or else add the missing widths, weights and shapes to the tables C<%FD_WIDTH>, +C<%FD_WEIGHT> and C<%FD_SHAPE>, near the top of the source code. +Please also send a bug report (see L<AUTHOR> below). + +B<autoinst> maps widths, weights and shapes to NFSS codes using +the following tables. These are based both on the standard I<Fontname> scheme +and on the tables in Philipp Lehman's F<Font Installation Guide>, +but some changes had to be made to avoid name clashes in font families +with many different widths and weights. + + + WEIGHT WIDTH + + Thin t Ultra Compressed up + Ultra Light ul Extra Compressed ep + Extra Light el Compressed, Compact p + Light l Compact p + Book [1] Ultra Condensed uc + Regular [1] Extra Condensed ec + Medium mb Condensed c + Demibold db Narrow n + Semibold sb Semicondensed sc + Bold b Regular [1] + Extra Bold eb Semiextended sx + Ultra ub Extended x + Ultra Bold ub Expanded e + Black k Wide w + Extra Black ek + Ultra Black uk + Heavy h SHAPE + Poster r + Roman, Upright n [2] + Italic it + Cursive, Kursiv it + Oblique, Slanted it [3] + Incline(d) it [3] + + +=head3 Notes: =over 4 =item [1] -When I<both> weight and width are empty, the `series' attribute becomes `m'. +When I<both> weight and width are empty, the "series" attribute becomes "m". =item [2] -Mapping the `Oblique' shape to `it' instead of the canonical `sl' simplifies -B<autoinst>. Since font families with both `Italic' and `Oblique' shapes -probably do not exist (apart from Computer Modern), -this shouldn't cause problems in real life. +Adobe Silentium Pro contains two "Roman" shapes ("RomanI" and "RomanII"); +the first of these is mapped to "n", the second one to "it". =item [3] -To the best of my knowledge, the only font family that has two `Roman' shapes -is Silentium; since this has no `Italic' shape, -the `it' code is (ab)used for the `RomanII' shape. +Mapping the "Slanted", "Oblique" or "Inclined" shape to "it" instead of "sl" +simplifies B<autoinst>. Since font families with both italic and slanted +shapes do - to the best of my knowledge - not exist +(apart from Computer Modern, of course), +this shouldn't cause problems in real life. =back - -=head2 A note for MikTeX users -Calling F<otftotfm> with the B< --automatic> option (as B<autoinst> does by -default) requires a TeX-installation that uses the F<kpathsea> library; with -TeX-installations that implement their own directory searching -(such as MiKTeX) F<otftotfm> might complain that it -cannot find a writable F<texmf> directory and leave all generated F<tfm>, -F<vf>, F<enc> and F<map> files in the current working directory. -In that case, you need to move these to their correct destinations. -You also need to tell the dvi-driver (F<dvips>, F<dvipdfm>, F<pdfTeX> etc.) -about the new font map files; see the documentation for how this is done. +=head2 A note for MiKTeX users + +Automatically installing the fonts into a suitable TEXMF tree +(as B<autoinst> does by default) requires a TeX-installation that uses +the F<kpathsea> library; with TeX distributions that implement their +own directory searching (such as MiKTeX), B<autoinst> will complain that +it cannot find the F<kpsewhich> program and install all generated files +into subdirectories of the current directory. +If you use such a TeX distribution, you should either move these files +to their correct destinations by hand, or use the I<-target> option +(see L</"COMMAND-LINE OPTIONS"> below) to specify a TEXMF tree. -Also, some OpenType fonts lead to F<pl> and F<vpl> files that are too -big for MiKTeX's F<pltotf> and F<vptovf>; the versions from TeXLive -(F<http://tug.org/ftp/texlive/Contents/live/bin/win32/>) don't have this -problem. +Also, some OpenType fonts lead to F<pl> and F<vpl> files that +are too big for MiKTeX's F<pltotf> and F<vptovf>; +the versions that come with W32TeX (F<http://www.w32tex.org>) +and TeXLive (F<http://tug.org/texlive>) don't have this problem. =head1 COMMAND-LINE OPTIONS +You may use either one or two dashes before options, +and option names may be shortened to a unique prefix +(e.g., B<-enc> instead of B<-encoding>). + =over 4 -=item B< --encoding>=I<encoding[,encoding]> +=item B<-encoding>=I<encoding[,encoding]> + +Use the specified encodings for the text fonts. The default is "OT1,T1,LY1". +For each encoding, a file F<< <encoding>.enc >> (in all I<lowercase>) +should be somewhere where F<otftotfm> can find it. Suitable encoding files +for OT1, T1/TS1 and LY1 come with B<autoinst>. (Note that these files are +called F<fontools_ot1.enc> etc. to avoid name clashes with other packages; +the "fontools_" prefix doesn't need to be specified.) -Use the encoding I<encoding> for the text fonts. The default is `LY1'. -A file named `<I<encoding>>.enc' (in all I<lowercase>) should be somewhere -where F<otftotfm> can find it. Suitable encoding files -for LY1, OT1 and T1/TS1 come with I<fontools>. (Note that these files are -called I<fontools_xxx.enc> to avoid name clashes with other packages; -the `fontools_' prefix doesn't need to be specified.) +Multiple text encodings can be specified as a comma-separated list: +C<-encoding=OT1,T1>. The encodings are passed to F<fontenc> in the order +specified, so the last one will be the default text encoding. -Multiple text encodings can be specified as well: C< --encoding=OT1,T1,LY1>. -The encodings are passed to F<fontenc> in the order specified, -so the last one will be the default text encoding. +=item B<-sanserif> -=item B< --sanserif> +Install the font as a sanserif font, accessed via C<\sffamily> and C<\textsf>. +Note that the generated style file redefines C<\familydefault>, +so including it will still make this font the default text font. -Install the font as a sanserif font, accessed via C<\sffamily> and C<\textsf>. -Note that the generated style file redefines C<\familydefault>, -so including it will make this font the default text font. +=item B<-typewriter> -=item B< --typewriter> +Install the font as a typewriter font, accessed via C<\ttfamily> and +C<\texttt>. +Note that the generated style file redefines C<\familydefault>, +so including it will still make this font the default text font. -Install the font as a typewriter font, accessed via C<\ttfamily> and -C<\texttt>. -Note that the generated style file redefines C<\familydefault>, -so including it will make this font the default text font. +=item B<-ts1> -=item B< --ts1> +=item B<-nots1> -=item B< --nots1> +Turn the creation of TS1-encoded fonts on or off. The default is B<-ts1> +if the text encodings (see I<-encoding> above) include T1, +B<-nots1> otherwise. -Turn the creation of TS1-encoded fonts on or off. The default is B< --ts1> -if the text encodings (see I< --encoding> above) include T1, -B< --nots1> otherwise. +=item B<-smallcaps> -=item B< --smallcaps> +=item B<-nosmallcaps> -=item B< --nosmallcaps> +Turn the creation of small caps fonts on or off. The default is +B<-smallcaps>. -Turn the creation of small caps fonts on or off. The default is -B< --smallcaps>. +=item B<-swash> -=item B< --swash> +=item B<-noswash> -=item B< --noswash> +Turn the creation of swash fonts on or off. The default is B<-swash>. -Turn the creation of swash fonts on or off. The default is B< --swash>. +=item B<-titling> -=item B< --titling> +=item B<-notitling> -=item B< --notitling> +Turn the creation of titling fonts on or off. The default is B<-titling>. -Turn the creation of titling fonts on or off. The default is B< --notitling>. +=item B<-superiors> -=item B< --superiors> +=item B<-nosuperiors> -=item B< --nosuperiors> +Turn the creation of fonts with superior characters on or off. +The default is B<-superiors>. -Turn the creation of fonts with superior characters on or off. -The default is B< --superiors>. +=item B<-inferiors> -=item B< --inferiors> +=item B<-noinferiors> -=item B< --noinferiors> +Turn the creation of fonts with inferior digits on or off. +The default is B<-noinferiors>. -Turn the creation of fonts with inferior figures on or off. -The default is B< --noinferiors>. +=item B<-fractions> -=item B< --fractions> +=item B<-nofractions> -=item B< --nofractions> +Turn the creation of fonts with numerators and denominators on or off. +The default is B<-nofractions>. -Turn the creation of fonts with numerators and denominators on or off. -The default is B< --nofractions>. +=item B<-ornaments> -=item B< --ornaments> +=item B<-noornaments> -=item B< --noornaments> +Turn the creation of ornament fonts on or off. The default is B<-ornaments>. -Turn the creation of ornament fonts on or off. The default is B< --ornaments>. +=item B<-target>=I<DIRECTORY> -=item B< --manual> +Install all generated files into the TEXMF tree at I<DIRECTORY>. -Manual mode. By default, B<autoinst> immediately executes all F<otftotfm> -command lines it generates; with the B< --manual> option, these commands are -instead written to a batch command file (named `<I<font>>.bat', to make things -easier for our friends on Windows). Also, the generated F<otftotfm> command -lines specify the I< --pl> option and leave out the I< --automatic> option; -this causes human readable (and editable) F<pl> and F<vpl> files to be created -instead of the default F<tfm> and F<vf> files. +By default, B<autoinst> searches your $TEXMFLOCAL and $TEXMFHOME paths +and installs all files into subdirectories of the first writable TEXMF tree +it finds (or into subdirectories of the current directory, +if no writable directory is found). -=item B< --verbose> +B<Note>: this option gets overriden by the B<-manual> option! + +=item B<-manual> + +Manual mode. By default, B<autoinst> immediately executes all F<otftotfm> +command lines it generates; with the B<-manual> option, these commands are +instead written to a file F<autoinst.bat>. +Also, the generated F<otftotfm> command lines specify the I< --pl> option +(which tells F<otftotfm> to generate readable/editable F<pl> and F<vpl> files +instead of the default F<tfm> and F<vf> files) +and leave out the I< --automatic> option (which tells F<otftotfm> to +leave all generated files in the current directory, rather than install +them into your TEXMF tree). + +When using this option, you should run F<pltotf> and F<vptovf> after +executing all commands, +to convert the F<pl> and F<vf> files to F<tfm> and F<vf> format. + +B<Note>: this option overrides the B<-target> option! + +=item B<-verbose> Verbose mode; print detailed info about what B<autoinst> thinks it's doing. -=item B< --extra>=I<text> +=item B<-extra>=I<text> -Pass I<text> as options to I<otftotfm>. To prevent I<text> from accidentily +Pass I<text> as options to I<otftotfm>. To prevent I<text> from accidentily being interpreted as options to B<autoinst>, it should be properly quoted. +=item B<-figurekern> + +=item B<-nofigurekern> + +Some fonts provide kerning pairs for tabular figures. +This is probably unwanted (e.g., numbers in tables won't line up exactly). +The option B<-nofigurekern> adds extra I< --ligkern> options +to the command lines for I<otftotfm> to suppress such kerns +(but only for the "TLF" and "TOsF" families). +Since this leads to very long command lines (it adds one hundred such options) +and the problem affects only few fonts, the default is B<-figurekern>. + =back @@ -1568,52 +1770,48 @@ being interpreted as options to B<autoinst>, it should be properly quoted. Eddie Kohler's TypeTools (F<http://www.lcdf.org/type>). -Perl is usually pre-installed on Linux and Unix systems; -on Windows, try ActivePerl (available from F<http://www.activestate.com>) -or Strawberry Perl (F<http://strawberryperl.com>). +Perl is pre-installed on most Linux and Unix systems; +on Windows, try ActiveState's ActivePerl +(available from F<http://www.activestate.com>) +or Strawberry Perl (F<http://strawberryperl.com>). -XeTeX (F<http://www.tug.org/xetex>) is an extension of TeX -that can natively use any font installed in the operating system -(including both flavours of OpenType fonts) -without additional support files. +XeTeX (F<http://www.tug.org/xetex>) and LuaTeX (F<http://www.luatex.org>) +are TeX extensions that can use any font (including both flavours of OpenType) +without TeX-specific support files. -John Owens' F<otfinst> (available from CTAN) is another wrapper +John Owens' F<otfinst> (available from CTAN) is another wrapper around F<otftotfm>, and may work when B<autoinst> doesn't. -The MinionPro for LaTeX project -(F<http://developer.berlios.de/projects/minionpro/>, also on CTAN) -developed very complete support files for Minion Pro (including math), +The MinionPro for LaTeX project +(F<http://developer.berlios.de/projects/minionpro/>, also on CTAN) +developed very complete support files for Minion Pro (including math), but the project appears to have been abandoned; -these files don't work with recent versions of Minion Pro. +these files don't work with the latest versions of Minion Pro. =head1 AUTHOR -Marc Penninga <marc@penninga.info> - -When sending a bug report, please give as much relevant information as -possible; this usually includes (but may not be limited to) the output from -running B<autoinst> with the B< --verbose> option. -Please make sure that this output includes all error messages (if any); -this can be done using the command +Marc Penninga <marcpenninga@gmail.com> -C<< autoinst I<(... all options and files ...)> E<gt>autoinst.log 2>&1 >> +When sending a bug report, please give as much relevant information as +possible; this includes at least (but may not be limited to) the output +from running B<autoinst> with the I<-verbose> option. +Please make sure that this output includes all (if any) error messages. =head1 COPYRIGHT -Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011 Marc Penninga. +Copyright (C) 2005-2012 Marc Penninga. =head1 LICENSE This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License -as published by the Free Software Foundation, -either version 2 of the License, or (at your option) -any later version. -A copy of the GNU General Public License is included with the I<fontools> -collection; see the file F<GPLv2.txt>. +it under the terms of the GNU General Public License as published +by the Free Software Foundation, either version 2 of the License, +or (at your option) any later version. +A copy of the GNU General Public License is included with B<autoinst>; +see the file F<GPLv2.txt>. =head1 DISCLAIMER @@ -1627,36 +1825,60 @@ GNU General Public License for more details. =head1 RECENT CHANGES -(See the source code for the full story.) +(See the source code for the rest of the story.) =over 12 +=item I<2012-03-06> + +Implemented the "splitting the font family into multiple subfamilies" +emergency strategy when font info parsing fails. +Added recognition for a number of unusual widths, weights and shapes. + +=item I<2012-02-29> + +Fixed a bug in the font parsing code, +where possible widths, weights and shapes where tested in the wrong order; +this led to "ExtraLight" fonts being recognised as "Light". +Added recognition for "Narrow" and "Wide" widths. +Also added the I<-(no)figurekern> command-line option. + +=item I<2012-02-01> + +Reorganised the code, and fixed some bugs in the process. +Added the I<-target> command-line option. +Made B<autoinst> install the F<fd> and F<sty> files in +the same TEXMF tree as the other generated files. +Generate OT1, T1 and LY1 encoded text fonts by default. +Made I<-titling> a default option (instead of I<-notitling>). +Updated the documentation. + =item I<2011-06-15> Fixed the font info parsing code for some fonts that are -too lazy to spell out 'Italic' in full. +too lazy to spell out "Italic" in full. =item I<2010-04-29> -The C< --feature=kern> option is only used for fonts that +The I< --feature=kern> option is only used for fonts that contain either a I<kern> feature or a I<kern> table. -Font feature selection commands in the F<.sty> file are only -generated for shapes and figure styles that are supported +Font feature selection commands in the F<sty> file are only +generated for shapes and figure styles that are supported by the current font, and whose generation has not been -turned off using the command line options. +turned off using the command-line options. Fixed the font info parsing to work with the Condensed fonts in the Minion Pro family. =item I<2010-04-23> -Always provide the C< --feature=kern> option to F<otftotfm>, -even if the font doesn't have a I<kern> feature; +Always provide the I< --feature=kern> option to F<otftotfm>, +even if the font doesn't have a I<kern> feature; this will make F<otftotfm> use the I<kern> table if present. -For fonts without a I<liga> feature, add C< --ligkern> +For fonts without a I<liga> feature, add I< --ligkern> options for the common f-ligatures to the F<otftotfm> command line, so that any ligatures present in the font will still be used. -Bug fix: the generated F<.sty> files now work for font families -with names containing digits. +Bug fix: the generated F<sty> files now work for font families +with names containing digits. =item I<2009-04-09> @@ -1665,13 +1887,16 @@ I<fontools_>, to prevent name clashes with other packages. =item I<2009-04-06> -A small patch to the C<make_ornament_encoding> subroutine; -it now also recognises the I<bullet.xxx> ornament glyphs -in Adobe's Kepler Pro. +A small patch to the C<get_orn> subroutine: +it now also recognises the I<bullet.xxx> ornament glyphs +in Adobe Kepler Pro. + +=back =begin Really_old_history +=over 12 =item I<2007-08-07> @@ -1680,17 +1905,17 @@ Fixed a small bug with filename quoting on Windows. =item I<2007-07-31> Changed the tables that map weights and widths to NFSS codes: -in some extended families (Helvetica Neue), different combinations of -weight and width were mapped to the same `series'. +in some extended families, different combinations of +weight and width were mapped to the same series. Added a work-around for incorrect size info in some Kepler fonts. -Fixed a small bug in the generated commands for otftotfm -(sometimes, the I< --onum> feature was included twice). +Fixed a small bug in the generated commands for otftotfm +(sometimes, the "onum" feature was included twice). Added encoding file for OT1 to the I<fontools> collection. =item I<2007-07-27> -Two bugfixes: a closing brace was missing in the generated style file, -and the NFSS series was formed as `width plus weight' instead of the reverse. +Two bugfixes: a closing brace was missing in the generated style file, +and the NFSS series was formed as "width plus weight" instead of the reverse. =item I<2007-06-10> @@ -1700,92 +1925,92 @@ caused problems for some other packages. =item I<2007-06-04> -Added the F< --no-updmap> option to all generated commands for F<otftotfm> +Added the I< --no-updmap> option to all generated commands for F<otftotfm> (except the last); this should yield a significant speed-up for large families (suggested by Steven E. Harris). Tweaked the font info parsing to work around a bug in the naming of some FontFont fonts, where every font is in a family of its own. -Added the `scaled' option (including the loading of F<xkeyval>) +Added the "scaled" option (including the loading of F<xkeyval>) to the generated style file. -Extended the output of the F< --verbose> option. +Extended the output of the I<-verbose> option. =item I<2007-02-08> -Yet Another Complete Rewrite. -The code is now much more readable and more flexible; +Yet Another Complete Rewrite. +The code is now much more readable and more flexible; the program can now handle fonts from different families, -as well as multiple text encodings. +as well as multiple text encodings. Rewrote the font info parsing code to work for Arno Pro. =item I<2006-10-11> The program determines the fonts' weights, widths and shapes by parsing -the output from F<otfinfo --info> instead of the font filename. -This should make B<autoinst> work for non-Adobe fonts. +the output from C<otfinfo --info> instead of the font filename. +This should make B<autoinst> work for non-Adobe fonts. Filenames with spaces now work as well. =item I<2006-08-31> -Made the generated style files try to include `fontaxes.sty'; -changed the names of the generated fonts and families +Made the generated style files try to include "fontaxes.sty"; +changed the names of the generated fonts and families (to make the previous change possible); -added command line options for most font styles and shapes; +added command-line options for most font styles and shapes; tweaked the filename parsing code for Cronos Pro and Gill Sans Pro; added runtime generation of encoding vectors for ornament fonts (because GaramondPremier's ornament names differ from other fonts); -changed the NFSS-code for italic small caps and titling to `scit' and `tlit' -(to work with F<fontaxes>); +changed the NFSS-code for italic small caps and titling to "scit" and "tlit" +(to work with F<fontaxes>); and edited (and hopefully improved) the documentation. =item I<2005-10-03> -When creating LY1, T1, OT1 or TS1 encoded fonts, the I< --coding-scheme> -option is added to the commands for F<otftotfm>; this should make the +When creating LY1, T1, OT1 or TS1 encoded fonts, the I<-coding-scheme> +option is added to the commands for F<otftotfm>; this should make the generated F<pl> and F<vpl> files acceptable to I<fontinst>. Also elaborated the documentation somewhat and fixed a small bug. =item I<2005-09-22> -Added check to see if filename parsing succeeded; -updated the filename parsing code to cater for GaramondPremier, Silentium +Added check to see if filename parsing succeeded; +updated the filename parsing code to cater for GaramondPremier, Silentium and some non-Adobe fonts; -added the B< --sanserif> and B< --typewriter> options and hacked the +added the I<-sanserif> and I<-typewriter> options and hacked the style files to support using several different font families in one document. =item I<2005-09-12> Cleaned up the code (it now runs under the F<strict> and F<warnings> pragmas); -fixed a (rather obscure) bug that occurred when creating TS1-encoded -fonts for families with multiple optical masters and oldstyle figures; +fixed a (rather obscure) bug that occurred when creating TS1-encoded +fonts for families with multiple optical masters and oldstyle digits; added the I<medium, semibold> etc. options to the style file; and improved the layout of the generated files. =item I<2005-08-11> The generated commands weren't actually executed, only printed.... -Also added a small hack to cater for fonts -(such as some recent versions of MinionPro) -that contain swash characters but don't provide a `swsh' feature. +Also added a small hack to cater for fonts +(such as some recent versions of MinionPro) +that contain swash characters but don't provide a "swsh" feature. =item I<2005-08-10> -Dropped the `fontname' scheme in favor of a more verbose naming scheme, -since many filenames were still more than eight characters long anyway. +Dropped the "fontname" scheme in favor of a more verbose naming scheme, +since many filenames were still more than eight characters long anyway. Added F<nfssext.sty>-like commands to the generated style file. -Changed the default encoding to LY1 and added the `inferior' shape. +Changed the default encoding to LY1 and added the "inferior" shape. =item I<2005-08-01> -Rewrote (and hopefully improved) the user interface; -changed the program to by default execute the generated F<otftotfm> command -lines rather than writing them to a file; -added automatic determination of the `fontname' code for the font family; -changed the NFSS code for italic small caps to `si'; added titling shapes; -changed the generated style -file to include an interface for the ornaments and to load Lehman's NFSS -extensions F<nfssext.sty> if this is installed; corrected the `fontname' codes +Rewrote (and hopefully improved) the user interface; +changed the program to by default execute the generated F<otftotfm> command +lines rather than writing them to a file; +added automatic determination of the "fontname" code for the font family; +changed the NFSS code for italic small caps to "si"; added titling shapes; +changed the generated style +file to include an interface for the ornaments and to load Lehman's NFSS +extensions F<nfssext.sty> if this is installed; corrected the "fontname" codes for OT1, T1, LY1 and user-specific encodings; extended the output generated by -the B< --verbose> option; and rewrote and extended the documentation. +the I<-verbose> option; and rewrote and extended the documentation. =item I<2005-06-16> |