summaryrefslogtreecommitdiff
path: root/info/symbols/comprehensive/source/makeREADME
blob: ba2c5d920bb926ed91338548de25909314341325 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#! /usr/bin/env perl

################################################
# Generate a README file for the Comprehensive #
# LaTeX Symbol List.                           #
#                                              #
# Author: Scott Pakin <scott+clsl@pakin.org>   #
################################################

use POSIX;
use warnings;
use strict;

###########################################################################

# Center a string within a given field length.
sub center_string ($$)
{
    my ($string, $fieldlen) = @_;
    my $prespaces = int (($fieldlen - length($string)) / 2);
    my $postspaces = $fieldlen - length($string) - $prespaces;

    return (" " x $prespaces) . $string . (" " x $postspaces);
}


# Format a list to a given number of columns.
sub format_list ($$@)
{
    my ($numcols, $textwidth, @list) = @_;
    my $itemwidth = int (($textwidth-4) / $numcols);

    my $col = 0;
    foreach my $item (@list) {
        print "    " if $col%$numcols==0;
        printf "%-${itemwidth}.${itemwidth}s", $item;
        print "\n" if ++$col%$numcols==0;
    }
    print "\n";
}


# Return the human-readable name of a PostScript font file.
sub find_pfb_name ($)
{
    my $pfb = $_[0];
    my $pfbfile = `kpsewhich $pfb`;
    die "${0}: Failed to locate $pfb\n" if !defined $pfbfile;
    chomp $pfbfile;
    local $/ = undef;
    open (PFBFILE, "<$pfbfile") || die "open(\"$pfbfile\"): $!\n";
    my $entirefile = <PFBFILE>;
    close PFBFILE or die "close(\"$pfbfile\"): $!\n";
    my $fullname;
    if ($entirefile =~ /FullName\s*\(([^\)]*)\)/) {
        # Best choice: FullName
        $fullname = $1;
        $fullname =~ s/\\(\d\d\d)/chr(oct($1))/ge;
        $fullname =~ s/^\s+//;
        $fullname =~ s/\s+$//;
    }
    elsif ($entirefile =~ m,FontName\s*/(\S+),) {
        # Tolerable: FontName
        $fullname = $1;
    }
    else {
        die "${pfbfile}: FullName not found\n";
    }
    return $fullname;
}


# Return the human-readable name of a TrueType font file.
sub find_ttf_name ($)
{
    my $ttf = $_[0];
    my $ttffile = `kpsewhich $ttf`;
    die "${0}: Failed to locate $ttf\n" if !defined $ttffile;
    chomp $ttffile;
    my %key_value;
    local $/ = "\n";
    open(TTFFILE, "otfinfo --info $ttffile|") || die "open(\"$ttffile\"): $!\n";
    while (my $ln = <TTFFILE>) {
        chomp $ln;
        next if $ln !~ /^([^:]+):\s*(.*)$/;
        $key_value{$1} = $2;
    }
    close TTFFILE or die "close(\"$ttffile\"): $!\n";
    foreach my $key ("Full name",
                     "Preferred family",
                     "Family",
                     "PostScript name") {
        my $val = $key_value{$key};
        return $val if $val ne "";
    }
    die "${ttffile}: Font information not found\n";
}


# Output all PostScript and TrueType font files and their associated,
# human-readable font name.
sub format_scalable_list ($\@)
{
    my $itemwidth = $_[0];
    foreach my $fname (@{$_[1]}) {
        my $fullname;
        if ($fname =~ /\.pfb$/) {
            $fullname = find_pfb_name $fname;
        }
        elsif ($fname =~ /\.ttf$/) {
            $fullname = find_ttf_name $fname;
        }
        else {
            die "${0}: Unrecognized file type for $fname\n";
        }
        printf "    %-${itemwidth}.${itemwidth}s (%s)\n", $fname, $fullname;
    }
}


# Sort a list and discard duplicates.
sub sort_unique (@)
{
    my %uniq;
    foreach my $e (@_) {
        $uniq{$e} = 1;
    }
    return sort keys %uniq;
}

###########################################################################

# Check the command-line arguments.
die "Usage: $0 <.log file> <.ind file>\n" if $#ARGV<1;
my ($logfilename, $indfilename) = @ARGV;

# Get the symbol count from the index file.
my $numsymbols = 0;
open (INDFILE, "<$indfilename") || die "open(): $!\nStopped";
while (<INDFILE>) {
    /\\item \\(sp)?verb/ && $numsymbols++;
}
close INDFILE;
my $roundnumsymbols = int($numsymbols/100) * 100;

# Read an entire pdflatex log file.
open (LOGFILE, "<$logfilename") || die "open(): $!\nStopped";
undef $/;
my $logfile = <LOGFILE>;
$logfile =~ s/\n//g;
close LOGFILE;

# Get a list of .mf files (indirectly via corresponding .pk files), .pfb,
# and .ttf files referenced by the log file.
my @mffiles = sort_unique map {"$_.mf"} ($logfile =~ m!<(?:[^>]+/)?([^/<>.]+)\.\d+pk>!g);
my @scalable_files = sort_unique ($logfile =~ m!<(?:[^>]+/)?([^/<>.]+\.(?:pfb|ttf))>!g);

# Tally the number of unique typefaces in @mffiles and @scalable_files.
my %allfonts;
foreach (@mffiles, @scalable_files) {
    my $fname = $_;
    $fname =~ s/\.(ttf|pfb|mf)$//;
    $fname =~ s/\d+$//;
    $allfonts{$fname} = 1;
}
my $numtypefaces = keys %allfonts;

# Write the README header.
my $date = strftime "%d %B %Y", localtime;
$date =~ s/\b0+/ /g;
my $headerwidth = 40;
my $linewidth = 75;
my $centerspace = " " x int(($linewidth-$headerwidth)/2);
printf "%s+-%s-+\n", $centerspace, ("-" x ($headerwidth-4));
printf "%s| %s |\n",
    $centerspace,
    center_string("THE COMPREHENSIVE LATEX SYMBOL LIST", $headerwidth-4);
printf "%s| %s |\n",
    $centerspace,
    center_string("By Scott Pakin, scott+clsl\@pakin.org", $headerwidth-4);
printf "%s| %s |\n",
    $centerspace,
    center_string("", $headerwidth-4);
printf "%s| %s |\n",
    $centerspace,
    center_string($date, $headerwidth-4);
printf "%s+-%s-+\n", $centerspace, ("-" x ($headerwidth-4));

# Output some text.
print <<"EOF1";

The Comprehensive LaTeX Symbol List is an organized list of over $roundnumsymbols
symbols commonly available to LaTeX users.  Some of these symbols are
guaranteed to be available in every TeX distribution.  Others require
font files that come with some, but not all, TeX distributions.  The
rest require font files that must be downloaded explicitly from CTAN
(http://www.ctan.org/) and installed.  The Comprehensive LaTeX Symbol
List currently showcases symbols from $numtypefaces separate typefaces.

The same directory that contains this README file also contains
SYMLIST (an ASCII list of symbols that appear in the symbols list) and
prebuilt versions of the symbol list for both A4 and U.S. Letter sized
paper.  If you'd like to build symbols.tex yourself (not recommended
for normal use), a Makefile is provided.  symbols.tex tries to be
smart about fonts; it omits tables of symbols that require (seemingly)
unavailable fonts.  The "Document Characteristics" table at the end of
the document lists the packages that were unavailable during the
build.

The prebuilt versions of the symbol list use primarily Type 1 fonts.
Type 1 fonts are scalable and should look good at any resolution and on
any output device.  However, some of the fonts used by symbols.tex are
available only in a METAFONT-generated bitmap format.  The prebuilt
symbol lists utilize 1200 DPI versions of all of the bitmapped fonts as
1200 DPI is a reasonably high printer resolution and therefore should
obscure the artifacts of bitmap rendering.

The following bitmapped fonts were used to typeset the symbol list:

EOF1

format_list (3, $linewidth, @mffiles);

print <<"EOF2";

For completeness, the following scalable fonts (some converted from
OpenType to PostScript Type 1) were used to typeset the symbol list:

EOF2

format_scalable_list (22, @scalable_files);