summaryrefslogtreecommitdiff
path: root/info/symbols/comprehensive/source/makerawtables
diff options
context:
space:
mode:
Diffstat (limited to 'info/symbols/comprehensive/source/makerawtables')
-rwxr-xr-xinfo/symbols/comprehensive/source/makerawtables292
1 files changed, 292 insertions, 0 deletions
diff --git a/info/symbols/comprehensive/source/makerawtables b/info/symbols/comprehensive/source/makerawtables
new file mode 100755
index 0000000000..34cfc6f709
--- /dev/null
+++ b/info/symbols/comprehensive/source/makerawtables
@@ -0,0 +1,292 @@
+#! /usr/bin/env perl
+
+#############################################
+# Create a massive table of every character #
+# in every font used in the Comprehensive #
+# LaTeX Symbol List #
+# #
+# By Scott Pakin <scott+clsl@pakin.org> #
+#############################################
+
+use Getopt::Long;
+use File::Basename;
+use warnings;
+use strict;
+
+# Parse the command line.
+my $paper = "letter";
+my $usagestr = "Usage: $0 [--paper=<letter|a4>]\n";
+GetOptions("p|paper=s" => \$paper) || die $usagestr;
+my ($paperwidth, $paperheight);
+if ($paper eq "letter") {
+ $paperwidth = "8.5in";
+ $paperheight = "11in";
+}
+elsif ($paper eq "a4") {
+ $paperwidth = "210mm";
+ $paperheight = "297mm";
+}
+else {
+ die $usagestr;
+}
+
+# Define a comparison function to use for sorting font names.
+sub compare_names ($$)
+{
+ return lc($_[0]) cmp lc($_[1]) || $_[0] cmp $_[1];
+}
+
+# Define a subroutine that returns a list of valid font names to process.
+sub find_valid_fonts ()
+{
+ # Build the CLSL under strace to acquire a list of .tfm files.
+ my %unique_tfms;
+ open(STRACE, "strace -e trace=open -s 32768 -f pdflatex -jobname symbols-letter-pdf '\\RequirePackage{snapshot}\\PassOptionsToClass{letterpaper}{article}\\input symbols' 2>&1|") || die "open: $!\n";
+ while (my $oneline = <STRACE>) {
+ print $oneline;
+ next if $oneline !~ /open\(\"(.*?)\.tfm\",.*\)\s+=\s+(\S+)/;
+ my ($tfm, $retcode) = (basename($1), $2);
+ next if $retcode eq "-1";
+ $unique_tfms{$tfm} = 1;
+ }
+ close STRACE || die;
+ my @tfmlist = sort compare_names keys %unique_tfms;
+
+ # Produce one table per font (overwriting as we go) to determine which
+ # fonts are missing, then remove those from the TFM list.
+ foreach my $tfm (@tfmlist) {
+ print "\n*** TESTING $tfm ***\n";
+ open(PDFTEX, "|pdftex testfont") || die "open: $!\n";
+ print PDFTEX $tfm, "\n";
+ print PDFTEX "\\table\n";
+ print PDFTEX "\\bye\n";
+ close PDFTEX || do {
+ print "*** DISCARDING $tfm ***\n";
+ delete $unique_tfms{$tfm};
+ };
+ }
+ @tfmlist = sort compare_names keys %unique_tfms;
+
+ # For fonts that come in multiple sizes, discard all but the closest to 10 pt.
+ my %base2tfms;
+ foreach my $tfm (@tfmlist) {
+ if ($tfm =~ /^(\D+)\d+$/) {
+ push @{$base2tfms{$1}}, $tfm;
+ }
+ else {
+ push @{$base2tfms{$tfm}}, $tfm;
+ }
+ }
+ while (my ($base, $tfmref) = each %base2tfms) {
+ my @tfms = @$tfmref;
+ if ($#tfms == 0) {
+ $base2tfms{$base} = $tfms[0];
+ next;
+ }
+ my @sizes = map {/(\d+)/; $1 >= 100 ? $1/1000 : $1} @tfms;
+ my ($best_tfm, $least_badness) = (0, 2**30);
+ foreach my $i (0 .. $#sizes) {
+ my $bad = ($sizes[$i] - 10)**2;
+ if ($bad < $least_badness) {
+ $best_tfm = $tfms[$i];
+ $least_badness = $bad;
+ }
+ }
+ print "*** RETAINING ONLY $best_tfm OUT OF [@tfms] ***\n";
+ $base2tfms{$base} = $best_tfm;
+ }
+ @tfmlist = sort compare_names values %base2tfms;
+ return @tfmlist;
+}
+
+# Use the font list from a prior run if available. Otherwise, process
+# symbols.tex to acquire a list of valid fonts.
+my @tfmlist;
+if (-e "rawtables.list") {
+ open(LIST, "<", "rawtables.list") || die "open: $!\n";
+ chomp(@tfmlist = <LIST>);
+ close LIST;
+}
+else {
+ # Slow path -- process symbols.tex using strace.
+ @tfmlist = find_valid_fonts();
+
+ # Dump the list of font names to disk to use for speeding up
+ # subsequent runs.
+ open(LIST, ">", "rawtables.list") || die "open: $!\n";
+ print LIST join("\n", @tfmlist), "\n";
+ close LIST;
+}
+
+# Determine the number of tables starting with each letter of the
+# alphabet to use for creating a PDF bookmarks list.
+my %lettertally;
+foreach my $tfm (@tfmlist) {
+ $lettertally{uc(substr $tfm, 0, 1)}++;
+}
+
+# Produce a series of font tables in a single PDF file.
+open(PDFTEX, ">", "rawtables-$paper.tex") || die "open: $!\n";
+printf PDFTEX "\% Specify %s paper.\n", $paper eq "a4" ? "A4" : "U.S. letter-sized";
+print PDFTEX "\\pdfpagewidth=$paperwidth\n";
+print PDFTEX "\\pdfpageheight=$paperheight\n";
+print PDFTEX <<'TESTFONT';
+
+% Define this document's metadata.
+\pdfinfo {
+ /Title (Raw Font Tables)
+ /Author (Scott Pakin <scott+clsl@pakin.org>)
+ /Subject (Tables of fonts used in the Comprehensive LaTeX Symbol List)
+ /Keywords (font tables, symbols, glyphs, characters, TeX, LaTeX)
+}
+
+% \reserve@table@space, which was derived from needspace.sty, ensures
+% that there is enough space remaining on the page for a complete font
+% table.
+\catcode`\@=11
+\newdimen\dimen@
+\newdimen\dimen@ii
+\def\reserve@table@space{%
+ \par \penalty-100\begingroup
+ \dimen@=\ht\tablebox
+ \dimen@ii\pagegoal \advance\dimen@ii-\pagetotal
+ \ifdim \dimen@>\dimen@ii
+ \ifdim \dimen@ii>\z@
+ \vfil
+ \fi
+ \break
+ \fi\endgroup
+}
+
+% \findfirstletter sets \firstletter to the first letter of its argument.
+\let\prevfirstletter=?
+\def\findfirstletter#1{\findfirstletter@i#1\null}
+\def\findfirstletter@i#1#2\null{\uppercase{\gdef\firstletter{#1}}}
+
+% \fonttable typesets a single font table given a count of fonts starting
+% with the same letter and a font name.
+\newbox\tablebox
+\def\fonttable#1#2{%
+ % Start a new page if we don't have enough space on the current one.
+ \def\fontname{#2}%
+ \setbox\tablebox=\vbox{\startfont\table}%
+ \reserve@table@space
+ % Start a new top-level bookmark for each letter of the alphabet.
+ \findfirstletter{#2}%
+ \ifx\firstletter\prevfirstletter
+ \else
+ \vfill\eject
+ \pdfdest name {\firstletter-fonts} xyz
+ \pdfoutline goto name {\firstletter-fonts} count -#1 {\firstletter}
+ \centerline{\sectionfont\firstletter}\par
+ \vskip1cm
+ \let\prevfirstletter=\firstletter
+ \fi
+ % Output a font table.
+ \pdfdest name {#2} xyz
+ \pdfoutline goto name {#2} {#2}
+ \startfont
+ \table
+ \vskip1cm plus 24pt minus 24pt
+}
+
+% Prepare fonts we'll need for the text.
+\input plnfss
+\input ot1cm.pfd
+\font\titlefont=cmbcsc10 at 24pt
+\font\symbolfont=cmsy10 at 12pt
+\def\symchar#1{{\symbolfont\char#1}}
+\font\manfnt=logo10 at 12pt
+\font\sectionfont=cminch
+
+% \LaTeX typesets the LaTeX logogram in either roman or italic. The
+% code was derived from the definition of \LaTeX in texnames.sty.
+\def\LaTeX{%
+ \ifdim\fontdimen1\font>0pt
+ \bgroup
+ \itshape
+ L\kern-.36em\raise.3ex\hbox{\setfontsize{10pt}\itshape A}\kern-.23em\TeX
+ \egroup
+ \else
+ L\kern-.36em\raise.3ex\hbox{\setfontsize{10pt}\selectfont A}\kern-.16em\TeX
+ \fi
+}
+
+% \MF typesets the Metafont logogram.
+\def\MF{{\manfnt METAFONT}}
+
+% \CLSL is a shortcut for "Comprehensive LaTeX Symbol List".
+\def\CLSL{\textit{Comprehensive \LaTeX\ Symbol List}}
+
+% Typeset some title text.
+\pdfdest name {title} xyz
+\pdfoutline goto name {title} {Title page}
+\setfontsize{12pt}\usefont{OT1}{cmr}{m}{n}
+{\titlefont\centerline{Raw Font Tables}\par}
+\vskip10pt
+{\setfontsize{14pt}\usefont{OT1}{cmr}{m}{n}%
+ \centerline{Scott Pakin, \textit{scott+clsl@pakin.org}}\par}
+\vskip10pt
+\centerline{%
+ \number\day \
+ \ifcase\month
+ \or January\or February\or March%
+ \or April\or May\or June%
+ \or July\or August\or September%
+ \or October\or November\or December%
+ \fi
+ \ \number\year
+}
+\vskip1cm
+%
+This document presents, in alphabetical order, font tables for all of
+the fonts that appear in the \CLSL. It was mechanically produced
+using a script that extracts the list of fonts used by the \CLSL\ and
+feeds this list into Knuth's \texttt{testfont.tex}, which is included
+in all \TeX\ distributions and can typeset font tables. The purpose
+of this document is to provide a companion mechanism for locating
+symbols by organizing the myriad symbols available to \TeX\ and
+\LaTeX\ by font family rather than by \LaTeX\ symbol name. It may
+also reveal some unnamed symbols---or symbols overlooked by the \CLSL.
+
+On the other hand, not every symbol shown in the \CLSL\ appears in
+this document. Some symbols are defined by juxtaposing multiple other
+symbols; some symbols are defined in terms of graphics primitives
+instead of fonts. The tables shown in this document are only those
+that correspond to ``true'' fonts---glyphs drawn in \MF, PostScript,
+or other such font formats and that have an associated \TeX\ font
+metric (\texttt{.tfm}) file.
+
+In each table, characters are numbered in both base~8 (octal) and
+base~16 (hexadecimal). A character's octal position is formed by
+taking the first two octal digits from a table's left column and the
+third octal digit from the top row. A character's hexadecimal
+position is formed by taking the first hexadecimal digit from a
+table's right column and the second hexadecimal digit from either the
+top or the bottom row, based on whether the character lies in the
+upper or lower row associated with the first hexadecimal digit. To
+clarify this description with an example, the ``\symchar{"34}'' symbol
+in the \texttt{cmsy10} table can be produced by either
+\texttt{\string\char'064} (octal) or \texttt{\string\char"34}
+(hexadecimal). The ``\symchar{"3C}'' symbol that lies directly
+beneath that in the table can be produced by either
+\texttt{\string\char'074} (octal) or \texttt{\string\char"3C}
+(hexadecimal). The decimal equivalents of these are
+\texttt{\string\char52} and \texttt{\string\char60}, and their
+character equivalents are ``\texttt{4}'' and ``\texttt{<}'',
+respectively.
+%
+\vfill\eject
+
+% Use Knuth's testfont.tex to typeset a bunch of tables.
+\let\noinit=!
+\input testfont
+TESTFONT
+;#`
+foreach my $tfm (@tfmlist) {
+ print "*** PRODUCING A TABLE FOR $tfm ***\n";
+ printf PDFTEX "\\fonttable{%d}{%s}\n", $lettertally{uc(substr $tfm, 0, 1)}, $tfm;
+}
+print PDFTEX "\\bye\n";
+close PDFTEX || die;
+print "*** SUCCESSFULLY CREATED rawtables-$paper.tex ***\n";