summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-09-26 23:06:02 +0000
committer <>2015-02-03 11:56:22 +0000
commite0b511b834f3529395df67126a7314097c2cf97e (patch)
tree89945ae53183ab2acdc61659c8b0b3e57e4a1f3a /contrib
parent2d8ae7b161658c4a589172db0072fc99f76fa979 (diff)
downloadtexinfo-tarball-master.tar.gz
Imported from /home/lorry/working-area/delta_texinfo-tarball/texinfo-5.2.tar.xz.HEADtexinfo-5.2master
Diffstat (limited to 'contrib')
-rw-r--r--contrib/README30
-rw-r--r--contrib/booklet.mak89
-rw-r--r--contrib/bright-colors.css212
-rw-r--r--contrib/deref.c208
-rwxr-xr-xcontrib/fix-info-dir317
-rwxr-xr-xcontrib/fixfonts84
-rw-r--r--contrib/fixref.gawk143
-rwxr-xr-xcontrib/gdoc911
-rwxr-xr-xcontrib/gen-dir-node211
-rwxr-xr-xcontrib/infosrch103
-rw-r--r--contrib/javaprop2texiflag.pl297
-rw-r--r--contrib/outline.gawk144
-rw-r--r--contrib/perldoc-all/GNUmakefile64
-rw-r--r--contrib/perldoc-all/README19
-rw-r--r--contrib/perldoc-all/gendocs_template76
-rw-r--r--contrib/perldoc-all/perldoc-all.texi34
-rw-r--r--contrib/prepinfo.awk355
-rwxr-xr-xcontrib/tex3patch70
-rw-r--r--contrib/texi-docstring-magic.el345
-rw-r--r--contrib/texifont/README31
-rw-r--r--contrib/texifont/enctest.tex45
-rw-r--r--contrib/texifont/fattr.tex803
-rw-r--r--contrib/texifont/fattr.tex.pairs644
-rw-r--r--contrib/texifont/fdefs.tex176
-rw-r--r--contrib/texifont/fsel.tex1703
-rw-r--r--contrib/texifont/ftest.tex445
-rw-r--r--contrib/texifont/ienc.tex544
-rw-r--r--contrib/texifont/oenc.tex990
-rw-r--r--contrib/texifont/otest.tex157
-rw-r--r--contrib/texifont/sample.cp125124
-rw-r--r--contrib/texifont/sample.koi8r24
-rw-r--r--contrib/texifont/sample.latin118
-rw-r--r--contrib/texifont/sample.latin218
-rw-r--r--contrib/texifont/sample.latin919
-rw-r--r--contrib/texifont/tests/Makefile29
-rw-r--r--contrib/texifont/tests/newfont.out76
-rw-r--r--contrib/texifont/tests/newfont.tex55
-rw-r--r--contrib/texifont/tests/subst.tex21
-rw-r--r--contrib/texifont/texifont.pdfbin0 -> 180951 bytes
-rw-r--r--contrib/texifont/texifont.txi680
-rw-r--r--contrib/txipsfonts-bronger.tex6601
-rw-r--r--contrib/txipsfonts-gildea.diff167
42 files changed, 16982 insertions, 0 deletions
diff --git a/contrib/README b/contrib/README
new file mode 100644
index 0000000..c416f44
--- /dev/null
+++ b/contrib/README
@@ -0,0 +1,30 @@
+$Id: README 5191 2013-02-23 00:11:18Z karl $
+texinfo/contrib/README
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved.
+
+The items here are for your amusement and/or hacking pleasure.
+See comments and/or --help strings in each for their purpose(s).
+
+They are all free software, but not officially part of Texinfo, and the
+Texinfo maintainers don't support them (and generally have no knowledge
+about them, just passing them on).
+
+The texifont/ subdirectory was an attempt at implementing a generalized
+font system, but it remains incomplete. See the README there.
+
+In contrast, the two txipsfonts-* files are attempts by Torsten Bronger
+and Stephen Gildea, respectively, to use base PostScript fonts instead
+of Computer Modern, in the simplest way. (I could not find the right
+version of the original texinfo.tex on which Torsten's file was based.)
+Adapting one of these to actually be installable would doubtless be much
+simpler (which is not to say simple) than finalizing texifont/, though
+of course much less featureful.
+
+The perldoc-all subdirectory is about making Texinfo out of the standard
+Perl *.pod files. The results are at
+http://www.gnu.org/software/perl/manual.
diff --git a/contrib/booklet.mak b/contrib/booklet.mak
new file mode 100644
index 0000000..e341251
--- /dev/null
+++ b/contrib/booklet.mak
@@ -0,0 +1,89 @@
+# -*- makefile -*-
+#
+# booklet.mak - making booklets from Texinfo.
+#
+# Copyright 2013 John Darrington.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# This makefile can be used to generate booklets from Texinfo sources.
+# It reduces each page to A5 size and renders two pages per sheet onto
+# A4 landscape. The pages are ordered into a "quire" or "gathering".
+# This means that you can print the result on a standard laser printer,
+# fold in half and using simple stapler bind the result into a
+# booklet.
+
+# Targets are <foo>-{a4,a5}-book.{dvi,ps,pdf} where <foo>.texi is the texinfo
+# source file.
+# It is suitable for Texinfo documents up to approx. 70 pages.
+
+# The *-a4-book targets produce A4 half area reduced pages. The *-a5-book
+# targets produce A5 full sized pages. The *a5-book option will therefore
+# have larger text, but will have a higher page count. It may also have
+# problems if the document has @display or @example environments with
+# long lines.
+
+# Example of use:
+# 1. make -f Makebook manual-a4-book.ps
+# 2. Print the result on a double sided laser printer. Alternatively
+# if your laser printer does not support double sided printing, print the ODD
+# numbered sheets, retreive the result from the printer and thinking carefully
+# about the page orientation, shove them back into the paper tray. Depending
+# on your printer, you may have to reverse the order of the sheets. Then print
+# the EVEN numbered sheets. I find gv usefull for this.
+# 3. Fold the result along the short dimension.
+# 4. Staple in place, using a long arm stapler.
+# 5. Using a guillotine cut the pages such that their edges co-incide.
+# 6. Sit back in an armchair and enjoy your reading.
+
+# For those of you who live in countries which refuse to conform to ISO 216,
+# you have a problem.
+
+# End of instructions.
+
+all:
+ echo 'Usage: make -f Makebook <target>'
+
+
+# Mutate the source, with appropriate headings, overriding anything that the
+# author has thoughtlessly imposed.
+# We want to specify the paper size, and double headings. Anything else?
+%-a4.texi: %.texi
+ sed -e 's/@afivepaper/@afourpaper/' -e '/@end titlepage/a @headings double' $< > $@
+
+%-a5.texi: %.texi
+ sed -e 's/@afourpaper/@afivepaper/' -e '/@end titlepage/a @headings double' $< > $@
+
+# Older versions of Texinfo break if the locale is non-english.
+%.dvi: %.texi
+ LC_ALL=C texi2dvi $< -o $@
+
+
+# Reorder the dvi into the correct order for the quire.
+%-sig.dvi: %.dvi
+ dvibook $< -o $@
+
+# Render 2 pages per sheet, ensuring there is an appropriate "gutter"
+%-a5-book.dvi: %-a5-sig.dvi
+ dvitodvi '2:0+1(148mm,0)' $< $@
+
+%-a4-book.dvi: %-a4-sig.dvi
+ dvitodvi '2:700@0(-15mm,-5mm)+1(210mm,-5mm)' $< $@
+
+# print the result in landscape orientation
+%.ps: %.dvi
+ dvips -t a4 -t landscape -t landscape $< -o $@
+
+%.pdf: %.ps
+ ps2pdf $< $@
+
+
+.PHONY: clean
+clean:
+ $(RM) *-a[54].*
diff --git a/contrib/bright-colors.css b/contrib/bright-colors.css
new file mode 100644
index 0000000..6e00447
--- /dev/null
+++ b/contrib/bright-colors.css
@@ -0,0 +1,212 @@
+/* === === === === === === === === === === === === === === === === ===
+
+ This file: texinfo_bright_colors.css
+ Version: 1.0
+ Date: September 13, 2010
+ Author: Jaakko Hollm@'en, e-mail: Jaakko.Hollmen@tkk.fi
+
+ The purpose of this cascading style sheet (CSS) style file named
+ "texinfo_bright_colors.css" is to introduce several bright and
+ contrasting colors for the structural elements of an HTML file.
+ The primary focus of the CSS style is to observe the sturucture
+ of HTML files created with Texinfo documentation system, more
+ specifically texi2html.
+
+ This is NOT a presentation style but a visualization of the
+ structure of an HTML file through coloring of the elements.
+ The style file may turn out to be useful for both developers of the
+ HTML outputting tools and the Texinfo documentation writers who
+ are interested to observe the outputted HTML structure.
+
+ The coloring has been achieved by associating a background-color
+ to important HTML elements. Minimal formatting has been done,
+ although the body font and the headers h1 to h5 have been given
+ absolute sizes, and some expanded space has been introduced to
+ horizontal rulers hr in order to make them more visible. There
+ are margins around the document resembling a book-like presentation
+ in the browser.
+
+ This Cascading Style Sheet (CSS) confroms to the CSS standard,
+ level 2.1. You can validate the correctness of your own
+ creation or modification of the current CSS style at the Web
+ address: http://jigsaw.w3.org/css-validator/ by one the three
+ input methods available.
+
+ If you edit your already produced HTML file generated by hand,
+ change the section <style>...</style> with
+
+ <link rel="stylesheet" href="./texinfo_bright_colors.css">
+
+ and put the CSS file in the same directory, or simply by
+ inclusion of the css file when compiling:
+
+ texi2dvi --css-include=texinfo_bright_colors.css my_doc.texi
+
+ Note: The output will be very "colorful", with very, very bright
+ colors. You have been warned.
+
+ --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
+
+ (c) Copyright, Jaakko Hollm@'en, Finland, Jaakko.Hollmen@tkk.fi
+ September, 2010
+
+ The current file "texinfo_bright_colors.css" 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 3 of the License, or (at your option)
+ any later version.
+
+ The current file "texinfo_bright_colors.css" is distributed in
+ the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ === === === === === === === === === === === === === === === === */
+
+body {
+margin: 30px 10% 30px 8%;
+background-color: white;
+font-family: serif;
+font-size: 1.0em;
+}
+
+h1 {
+font-size: 2.4em;
+background-color: #FF0000;
+}
+
+h2 {
+font-size: 2.0em;
+background-color: #FF0066;
+}
+
+h3 {
+font-size: 1.8em;
+background-color: #FF00CC;
+}
+
+h4 {
+font-size: 1.6em;
+background-color: #FF33FF;
+;
+}
+
+h5 {
+font-size: 1.4em;
+background-color: #FF99FF;
+}
+
+p {
+background-color: #B0B0B0;
+}
+
+blockquote {
+background-color: #FFCCFF;
+}
+
+div.shortcontents {
+background-color: #FF9900;
+}
+
+div.contents {
+background-color: #FF9900;
+}
+
+div.defun {
+background-color: #FF9900;
+}
+
+div.float {
+background-color: #FF9900;
+}
+
+div.footnote {
+background-color: #FF9900;
+}
+
+div.node {
+background-color: #FF9900;
+}
+
+ul {
+background-color: #FF9900;
+}
+
+ol {
+background-color: #CCFF33;
+}
+
+table {
+background-color: #FFFF00;
+}
+
+tr {
+background-color: #66FF00;
+}
+
+td {
+background-color: #66CC00;
+}
+
+dl {
+background-color: #00FF00;
+}
+
+dt {
+background-color: #66CC00;
+}
+
+dd {
+background-color: #00FFFF;
+}
+
+pre.display {
+background-color: #33CCFF;
+}
+
+pre.smalldisplay {
+background-color: #33CCFF;
+}
+
+pre.example {
+background-color: #33CCFF;
+}
+
+pre.smallexample {
+background-color: #33CCFF;
+}
+
+pre.format {
+background-color: #33CCFF;
+}
+
+pre.smallformat {
+background-color: #33CCFF;
+}
+
+pre.lisp {
+background-color: #33CCFF;
+}
+
+pre.smalllisp {
+background-color: #33CCFF;
+}
+
+pre.sp {
+background-color: #33CCFF;
+}
+
+pre.verbatim {
+background-color: #33CCFF;
+}
+
+code {
+background-color: #00FF00;
+}
+
+hr {
+background-color: #0000FF;
+margin: 0.5em;
+padding: 0.5em;
+}
diff --git a/contrib/deref.c b/contrib/deref.c
new file mode 100644
index 0000000..98e8ce0
--- /dev/null
+++ b/contrib/deref.c
@@ -0,0 +1,208 @@
+/*
+ * deref.c
+ *
+ * Make all texinfo references into the one argument form.
+ *
+ * Arnold Robbins
+ * arnold@gnu.org
+ * Written: December, 1991
+ * Released: November, 1998
+ *
+ * Copyright 1991, 1998 Arnold David Robbins
+ *
+ * DEREF 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * DEREF is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * LIMITATIONS:
+ * One texinfo cross reference per line.
+ * Cross references may not cross newlines.
+ * Use of fgets for input (to be fixed).
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+/* for gcc on the 3B1, delete if this gives you grief */
+extern int fclose(FILE *fp);
+extern int fprintf(FILE *fp, const char *str, ...);
+/* extern int sprintf(char *str, const char *fmt, ...); */
+extern int fputs(char *buf, FILE *fp);
+
+extern char *strerror(int errno);
+extern char *strchr(char *cp, int ch);
+extern int strncmp(const char *s1, const char *s2, int count);
+
+extern int errno;
+
+void process(FILE *fp);
+void repair(char *line, char *ref, int toffset);
+
+int Errs = 0;
+char *Name = "stdin";
+int Line = 0;
+char *Me;
+
+/* main --- handle arguments, global vars for errors */
+
+int
+main(int argc, char **argv)
+{
+ FILE *fp;
+
+ Me = argv[0];
+
+ if (argc == 1)
+ process(stdin);
+ else
+ for (argc--, argv++; *argv != NULL; argc--, argv++) {
+ if (argv[0][0] == '-' && argv[0][1] == '\0') {
+ Name = "stdin";
+ Line = 0;
+ process(stdin);
+ } else if ((fp = fopen(*argv, "r")) != NULL) {
+ Name = *argv;
+ Line = 0;
+ process(fp);
+ fclose(fp);
+ } else {
+ fprintf(stderr, "%s: can not open: %s\n",
+ *argv, strerror(errno));
+ Errs++;
+ }
+ }
+ return Errs != 0;
+}
+
+/* isref --- decide if we've seen a texinfo cross reference */
+
+int
+isref(char *cp)
+{
+ if (strncmp(cp, "@ref{", 5) == 0)
+ return 5;
+ if (strncmp(cp, "@xref{", 6) == 0)
+ return 6;
+ if (strncmp(cp, "@pxref{", 7) == 0)
+ return 7;
+ return 0;
+}
+
+/* process --- read files, look for references, fix them up */
+
+void
+process(FILE *fp)
+{
+ char buf[BUFSIZ];
+ char *cp;
+ int count;
+
+ while (fgets(buf, sizeof buf, fp) != NULL) {
+ Line++;
+ cp = strchr(buf, '@');
+ if (cp == NULL) {
+ fputs(buf, stdout);
+ continue;
+ }
+ do {
+ count = isref(cp);
+ if (count == 0) {
+ cp++;
+ cp = strchr(cp, '@');
+ if (cp == NULL) {
+ fputs(buf, stdout);
+ goto next;
+ }
+ continue;
+ }
+ /* got one */
+ repair(buf, cp, count);
+ break;
+ } while (cp != NULL);
+ next: ;
+ }
+}
+
+/* repair --- turn all texinfo cross references into the one argument form */
+
+void
+repair(char *line, char *ref, int toffset)
+{
+ int braces = 1; /* have seen first left brace */
+ char *cp;
+
+ ref += toffset;
+
+ /* output line up to and including left brace in reference */
+ for (cp = line; cp <= ref; cp++)
+ putchar(*cp);
+
+ /* output node name */
+ for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
+ putchar(*cp);
+
+ if (*cp != '}') { /* could have been one arg xref */
+ /* skip to matching right brace */
+ for (; braces > 0; cp++) {
+ switch (*cp) {
+ case '@':
+ cp++; /* blindly skip next character */
+ break;
+ case '{':
+ braces++;
+ break;
+ case '}':
+ braces--;
+ break;
+ case '\n':
+ case '\0':
+ Errs++;
+ fprintf(stderr,
+ "%s: %s: %d: mismatched braces\n",
+ Me, Name, Line);
+ goto out;
+ default:
+ break;
+ }
+ }
+ out:
+ ;
+ }
+
+ putchar('}');
+ if (*cp == '}')
+ cp++;
+
+ /* now the rest of the line */
+ for (; *cp; cp++)
+ putchar(*cp);
+ return;
+}
+
+/* strerror --- return error string, delete if in your library */
+
+char *
+strerror(int errno)
+{
+ static char buf[100];
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+
+ if (errno < sys_nerr && errno >= 0)
+ return sys_errlist[errno];
+
+ sprintf(buf, "unknown error %d", errno);
+ return buf;
+}
diff --git a/contrib/fix-info-dir b/contrib/fix-info-dir
new file mode 100755
index 0000000..b1144ed
--- /dev/null
+++ b/contrib/fix-info-dir
@@ -0,0 +1,317 @@
+#!/bin/sh
+#fix-info-dir (GNU texinfo)
+VERSION=1.1
+#Copyright (C) 1998, 2003 Free Software Foundation, Inc.
+#fix-info-dir comes with NO WARRANTY, to the extent permitted by law.
+#You may redistribute copies of fix-info-dir
+#under the terms of the GNU General Public License.
+#For more information about these matters, see the files named COPYING."
+#fix-info-dir was derived from update-info and gen-dir-node
+# The skeleton file contains info topic names in the
+# order they should appear in the output. There are three special
+# lines that alter the behavior: a line consisting of just "--" causes
+# the next line to be echoed verbatim to the output. A line
+# containing just "%%" causes all the remaining filenames (wildcards
+# allowed) in the rest of the file to be ignored. A line containing
+# just "!!" exits the script when reached (unless preceded by a line
+# containing just "--").
+#Author: Richard L. Hawes, rhawes@dmapub.dma.org.
+
+# ###SECTION 1### Constants
+set -h 2>/dev/null
+# ENVIRONMENT
+if test -z "$TMPDIR"; then
+ TMPDIR="/usr/tmp"
+fi
+if test -z "$LINENO"; then
+ LINENO="0"
+fi
+
+MENU_BEGIN='^\*\([ ]\)\{1,\}Menu:'
+MENU_ITEM='^\* ([^ ]).*:([ ])+\('
+MENU_FILTER1='s/^\*\([ ]\)\{1,\}/* /'
+MENU_FILTER2='s/\([ ]\)\{1,\}$//g'
+
+TMP_FILE1="${TMPDIR}/fx${$}.info"
+TMP_FILE2="${TMPDIR}/fy${$}.info"
+TMP_FILE_LIST="$TMP_FILE1 $TMP_FILE2"
+
+TRY_HELP_MSG="Try --help for more information"
+
+# ###SECTION 100### main program
+#variables set by options
+CREATE_NODE=""
+DEBUG=":"
+MODE=""
+#
+Total="0"
+Changed=""
+
+while test "$*"; do
+ case "$1" in
+ -c|--create) CREATE_NODE="y";;
+ --debug) set -eux; DEBUG="set>&2";;
+ -d|--delete) MODE="Detect_Invalid";;
+ +d);;
+ --version)
+cat<<VersionEOF
+fix-info-dir (GNU Texinfo) $VERSION
+Copyright (C) 1998 Free Software Foundation, Inc.
+fix-info-dir comes with NO WARRANTY, to the extent permitted by law.
+You may redistribute copies of fix-info-dir
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING.
+Author: Richard L. Hawes
+VersionEOF
+ exit;;
+
+ --help)
+cat<<HelpEndOfFile
+Usage: fix-info-dir [OPTION]... [INFO_DIR/[DIR_FILE]] [SKELETON]
+
+It detects and inserts missing menu items into the info dir file.
+The info dir must be the current directory.
+
+Options:
+-c, --create create a new info node
+-d, --delete delete invalid menu items (ignore missing menu items)
+ --debug print debug information to standard error path
+ --help print this help message and exit
+ --version print current version and exit
+Backup of the info node has a '.old' suffix added. This is a shell script.
+Environment Variables: TMPDIR
+Email bug reports to bug-texinfo@gnu.org.
+HelpEndOfFile
+ exit;;
+
+ [-+]*) echo "$0:$LINENO: \"$1\" is not a valid option">&2
+ echo "$TRY_HELP_MSG">&2
+ exit 2;;
+ *) break;;
+ esac
+ shift
+done
+
+ORIGINAL_DIR=`pwd`
+
+if test "$#" -gt "0"; then
+ INFO_DIR="$1"
+ shift
+else
+ INFO_DIR=$DEFAULT_INFO_DIR
+fi
+
+if test ! -d "${INFO_DIR}"; then
+ DIR_FILE=`basename ${INFO_DIR}`;
+ INFO_DIR=`dirname ${INFO_DIR}`;
+else
+ DIR_FILE="dir"
+fi
+
+cd "$INFO_DIR"||exit
+
+
+if test "$CREATE_NODE"; then
+ if test "$#" -gt "0"; then
+ if test `expr $1 : /` = '1'; then
+ SKELETON="$1"
+ else
+ SKELETON="$ORIGINAL_DIR/$1"
+ fi
+ if test ! -r "$SKELETON" && test -f "$SKELETON"; then
+ echo "$0:$LINENO: $SKELETON is not readable">&2
+ exit 2
+ fi
+ shift
+ else
+ SKELETON=/dev/null
+
+ fi
+else
+ if test ! -f "$DIR_FILE"; then
+ echo "$0:$LINENO: $DIR_FILE is irregular or nonexistant">&2
+ exit 2
+ elif test ! -r "$DIR_FILE"; then
+ echo "$0:$LINENO: $DIR_FILE is not readable">&2
+ exit 2
+ elif test ! -w "$DIR_FILE"; then
+ echo "$0:$LINENO: $DIR_FILE is not writeable">&2
+ exit 2
+ fi
+fi
+
+if test "$#" -gt "0"; then
+ echo "$0:$LINENO: Too many parameters">&2
+ echo "$TRY_HELP_MSG">&2
+ exit 2
+fi
+
+if test -f "$DIR_FILE"; then
+ cp "$DIR_FILE" "$DIR_FILE.old"
+ echo "Backed up $DIR_FILE to $DIR_FILE.old."
+fi
+
+if test "$CREATE_NODE"; then
+ if test "$MODE"; then
+ echo "$0:$LINENO: ERROR: Illogical option combination: -d -c">&2
+ echo "$TRY_HELP_MSG">&2
+ exit 2
+ fi
+ echo "Creating new Info Node: `pwd`/$DIR_FILE"
+ Changed="y"
+
+{
+
+ ### output the dir header
+ echo "-*- Text -*-"
+ echo "This file was generated automatically by $0."
+ echo "This version was generated on `date`"
+ echo "by `whoami`@`hostname` for `pwd`"
+
+ cat<<DIR_FILE_END_OF_FILE
+This is the file .../info/$DIR_FILE, which contains the topmost node of the
+Info hierarchy. The first time you invoke Info you start off
+looking at that node, which is ($DIR_FILE)Top.
+
+
+File: $DIR_FILE Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs topic, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu: The list of major topics begins on the next line.
+
+DIR_FILE_END_OF_FILE
+
+### go through the list of files in the skeleton. If an info file
+### exists, grab the ENTRY information from it. If an entry exists
+### use it, otherwise create a minimal $DIR_FILE entry.
+
+ # Read one line from the file. This is so that we can echo lines with
+ # whitespace and quoted characters in them.
+ while read fileline; do
+ # flag fancy features
+ if test ! -z "$echoline"; then # echo line
+ echo "$fileline"
+ echoline=""
+ continue
+ elif test "${fileline}" = "--"; then
+ # echo the next line
+ echoline="1"
+ continue
+ elif test "${fileline}" = "%%"; then
+ # skip remaining files listed in skeleton file
+ skip="1"
+ continue
+ elif test "${fileline}" = "!!"; then
+ # quit now
+ break
+ fi
+
+ # handle files if they exist
+ for file in $fileline""; do
+ fname=
+ if test -z "$file"; then
+ break
+ fi
+ # Find the file to operate upon.
+ if test -r "$file"; then
+ fname="$file"
+ elif test -r "${file}.info"; then
+ fname="${file}.info"
+ elif test -r "${file}.gz"; then
+ fname="${file}.gz"
+ elif test -r "${file}.info.gz"; then
+ fname="${file}.info.gz"
+ else
+ echo "$0:$LINENO: can't find info file for ${file}?">&2
+ continue
+ fi
+
+ # if we found something and aren't skipping, do the entry
+ if test "$skip"; then
+ continue
+ fi
+
+ infoname=`echo $file|sed -e 's/.info$//'`
+ entry=`zcat -f $fname|\
+ sed -e '1,/START-INFO-DIR-ENTRY/d'\
+ -e '/END-INFO-DIR-ENTRY/,$d'`
+ if [ ! -z "${entry}" ]; then
+ echo "${entry}"
+ else
+ echo "* ${infoname}: (${infoname})."
+ fi
+ Total=`expr "$Total" + "1"`
+ done
+ done
+}>$DIR_FILE<$SKELETON
+fi
+
+trap ' eval "$DEBUG"; rm -f $TMP_FILE_LIST; exit ' 0
+trap ' rm -f $TMP_FILE_LIST
+ exit ' 1
+trap ' rm -f $TMP_FILE_LIST
+ echo "$0:$LINENO: received INT signal.">&2
+ exit ' 2
+trap ' rm -f $TMP_FILE_LIST
+ echo "$0:$LINENO: received QUIT signal.">&2
+ exit ' 3
+
+sed -e "1,/$MENU_BEGIN/d" -e "$MENU_FILTER1" -e "$MENU_FILTER2"<$DIR_FILE\
+|sed -n -e '/\* /{
+s/).*$//g
+s/\.gz$//
+s/\.info$//
+s/^.*(//p
+}'|sort -u>$TMP_FILE1
+ls -F|sed -e '/\/$/d' -e '/[-.][0-9]/d'\
+ -e "/^$DIR_FILE\$/d" -e "/^$DIR_FILE.old\$/d"\
+ -e 's/[*@]$//' -e 's/\.gz$//' -e 's/\.info$//'|sort>$TMP_FILE2
+
+if test -z "$MODE"; then
+ #Detect Missing
+ DONE_MSG="total menu item(s) were inserted into `pwd`/$DIR_FILE"
+ for Info_Name in `comm -13 $TMP_FILE1 $TMP_FILE2`; do
+ if test -r "$Info_Name"; then
+ Info_File="$Info_Name"
+ elif test -r "${Info_Name}.info"; then
+ Info_File="${Info_Name}.info"
+ elif test -r "${Info_Name}.gz"; then
+ Info_File="${Info_Name}.gz"
+ elif test -r "${Info_Name}.info.gz"; then
+ Info_File="${Info_Name}.info.gz"
+ else
+ echo "$0:$LINENO: can't find info file for ${Info_Name}?">&2
+ continue
+ fi
+ Changed="y"
+ if install-info $Info_File $DIR_FILE; then
+ Total=`expr "$Total" + "1"`
+ fi
+ done
+else
+ # Detect Invalid
+ DONE_MSG="total invalid menu item(s) were removed from `pwd`/$DIR_FILE"
+ for Info_Name in `comm -23 $TMP_FILE1 $TMP_FILE2`; do
+ Changed="y"
+ if install-info --remove $Info_Name $DIR_FILE; then
+ Total=`expr "$Total" + "1"`
+ fi
+ done
+fi
+
+# print summary
+if test "$Changed"; then
+ echo "$Total $DONE_MSG"
+else
+ echo "Nothing to do"
+fi
+rm -f $TMP_FILE_LIST
+eval "$DEBUG"
+exit 0
diff --git a/contrib/fixfonts b/contrib/fixfonts
new file mode 100755
index 0000000..ee2ea71
--- /dev/null
+++ b/contrib/fixfonts
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Make links named `lcircle10' for all TFM and GF/PK files, if no
+# lcircle10 files already exist.
+
+# Don't override definition of prefix and/or libdir if they are
+# already defined in the environment.
+if test "z${prefix}" = "z" ; then
+ prefix=/usr/local
+else
+ # prefix may contain references to other variables, thanks to make.
+ eval prefix=\""${prefix}"\"
+fi
+
+if test "z${libdir}" = "z" ; then
+ libdir="${prefix}/lib/tex"
+else
+ # libdir may contain references to other variables, thanks to make.
+ eval libdir=\""${libdir}"\"
+fi
+
+texlibdir="${libdir}"
+texfontdir="${texlibdir}/fonts"
+
+# Directories for the different font formats, in case they're not all
+# stored in one place.
+textfmdir="${textfmdir-${texfontdir}}"
+texpkdir="${texpkdir-${texfontdir}}"
+texgfdir="${texgfdir-${texfontdir}}"
+
+test "z${TMPDIR}" = "z" && TMPDIR="/tmp"
+
+tempfile="${TMPDIR}/circ$$"
+tempfile2="${TMPDIR}/circ2$$"
+
+# EXIT SIGHUP SIGINT SIGQUIT SIGTERM
+#trap 'rm -f "${tempfile}" "${tempfile2}"' 0 1 2 3 15
+
+# Find all the fonts with names that include `circle'.
+(cd "${texfontdir}"; find . -name '*circle*' -print > "${tempfile}")
+
+# If they have lcircle10.tfm, assume everything is there, and quit.
+if grep 'lcircle10\.tfm' "${tempfile}" > /dev/null 2>&1 ; then
+ echo "Found lcircle10.tfm."
+ exit 0
+fi
+
+# No TFM file for lcircle. Make a link to circle10.tfm if it exists,
+# and then make a link to the bitmap files.
+grep 'circle10\.tfm' "${tempfile}" > "${tempfile2}" \
+ || {
+ echo "I can't find any circle fonts in ${texfontdir}.
+If it isn't installed somewhere else, you need to get the Metafont sources
+from somewhere, e.g., labrea.stanford.edu:pub/tex/latex/circle10.mf, and
+run Metafont on them."
+ exit 1
+ }
+
+# We have circle10.tfm. (If we have it more than once, take the first
+# one.) Make the link.
+tempfile2_line1="`sed -ne '1p;q' \"${tempfile2}\"`"
+ln "${tempfile2_line1}" "${textfmdir}/lcircle10.tfm"
+echo "Linked to ${tempfile2_line1}."
+
+# Now make a link for the PK files, if any.
+(cd "${texpkdir}"
+ for f in `grep 'circle10.*pk' "${tempfile}"` ; do
+ set - `echo "$f" \
+ | sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'`
+ ln "$f" "${1}/l${2}"
+ echo "Linked to $f."
+ done
+)
+
+# And finally for the GF files.
+(cd "${texgfdir}"
+ for f in `grep 'circle10.*gf' "${tempfile}"` ; do
+ set - `echo "$f" \
+ | sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'`
+ ln "$f" "${1}/l${2}"
+ echo "Linked to $f."
+ done
+)
+
+# eof
diff --git a/contrib/fixref.gawk b/contrib/fixref.gawk
new file mode 100644
index 0000000..4a692f7
--- /dev/null
+++ b/contrib/fixref.gawk
@@ -0,0 +1,143 @@
+#! /usr/local/bin/gawk -f
+
+# fixref.awk --- fix xrefs in texinfo documents
+# Copyright 1991, 1998 Arnold David Robbins
+
+# FIXREF 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 3 of the License, or
+# (at your option) any later version.
+#
+# FIXREF is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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, see <http://www.gnu.org/licenses/>.
+
+# Updated: Jul 21 1992 --- change unknown
+# Updated: Jul 18 1997 --- bug fix
+
+# usage: gawk -f fixref.awk input-file > output-file
+# or if you have #!: fixref.awk input-file > output-file
+
+# Limitations:
+# 1. no more than one cross reference on a line
+# 2. cross references may not cross a newline
+
+BEGIN \
+{
+ # we make two passes over the file. To do that we artificially
+ # tweak the argument vector to do a variable assignment
+
+ if (ARGC != 2) {
+ printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
+ exit 1
+ }
+ ARGV[2] = "pass=2"
+ ARGV[3] = ARGV[1]
+ ARGC = 4
+
+ # examine paragraphs
+ RS = ""
+
+ heading = "@(chapter|appendix|unnumbered|(appendix(sec|subsec|subsubsec))|section|subsection|subsubsection|unnumberedsec|heading|top)"
+
+ pass = 1
+
+ # put space between paragraphs on output
+ ORS = "\n\n"
+}
+
+pass == 1 && NF == 0 { next }
+
+# pass == 1 && /@node/ \
+# bug fix 7/18/96
+pass == 1 && /^@node/ \
+{
+ lname = name = ""
+ n = split($0, lines, "\n")
+ for (i = 1; i <= n; i++) {
+ if (lines[i] ~ ("^" heading)) {
+ sub(heading, "", lines[i])
+ sub(/^[ \t]*/, "", lines[i])
+ lname = lines[i]
+# printf "long name is '%s'\n", lines[i]
+ } else if (lines[i] ~ /@node/) {
+ sub(/@node[ \t]*/, "", lines[i])
+ sub(/[ \t]*,.*$/, "", lines[i])
+ name = lines[i]
+# printf "node name is '%s'\n", lines[i]
+ }
+ }
+ if (name && lname)
+ names[name] = lname
+ else if (lname)
+ printf("node name for %s missing!\n", lname) > "/dev/stderr"
+ else
+ printf("long name for %s missing!\n", name) > "/dev/stderr"
+
+ if (name ~ /:/)
+ printf("node `%s' contains a `:'\n", name) > "/dev/stderr"
+
+ if (lname) {
+ if (lname ~ /:/)
+ printf("name `%s' contains a `:'\n", lname) > "/dev/stderr"
+ else if (lname ~ /,/) {
+ printf("name `%s' contains a `,'\n", lname) > "/dev/stderr"
+ gsub(/,/, " ", lname)
+ names[name] = lname # added 7/18/97
+ }
+ }
+}
+
+pass == 2 && /@(x|px)?ref{/ \
+{
+ # split the paragraph into lines
+ # write them out one by one after fixing them
+ n = split($0, lines, "\n")
+ for (i = 1; i <= n; i++)
+ if (lines[i] ~ /@(x|px)?ref{/) {
+ res = updateref(lines[i])
+ printf "%s\n", res
+ } else
+ printf "%s\n", lines[i]
+
+ printf "\n" # avoid ORS
+ next
+}
+
+function updateref(orig, refkind, line)
+{
+ line = orig # work on a copy
+
+ # find the beginning of the reference
+ match(line, "@(x|px)?ref{")
+ refkind = substr(line, RSTART, RLENGTH)
+
+ # pull out just the node name
+ sub(/.*ref{/, "", line)
+ sub(/}.*$/, "", line)
+ sub(/,.*/, "", line)
+
+# debugging
+# printf("found ref to node '%s'\n", line) > "/dev/stderr"
+
+ # If the node name and the section name are the same
+ # we don't want to bother doing this.
+
+ if (! (line in names)) # sanity checking
+ printf("no long name for %s\n", line) > "/dev/stderr"
+ else if (names[line] != line && names[line] !~ /[:,]/) {
+ # build up new ref
+ newref = refkind line ", ," names[line] "}"
+ pat = refkind line "[^}]*}"
+
+ sub(pat, newref, orig)
+ }
+
+ return orig
+}
+
+pass == 2 { print }
diff --git a/contrib/gdoc b/contrib/gdoc
new file mode 100755
index 0000000..210965b
--- /dev/null
+++ b/contrib/gdoc
@@ -0,0 +1,911 @@
+eval '(exit $?0)' && eval 'exec perl -S "$0" ${1+"$@"}'
+ & eval 'exec perl -S "$0" $argv:q'
+ if 0;
+
+## Copyright (c) 2002-2012 Simon Josefsson
+## added -texinfo, -listfunc, -pkg-name
+## man page revamp
+## various improvements
+## Copyright (c) 2001, 2002 Nikos Mavrogiannopoulos
+## added -tex
+## Copyright (c) 1998 Michael Zucchi
+
+# 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 3 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
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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, see <http://www.gnu.org/licenses/>.
+
+# This will read a C source code file and scan for embedded comments
+# in the style of gnome comments (+minor extensions - see below).
+
+# usage:
+# gdoc [ -docbook | -html | -text | -man | -tex | -texinfo | -listfunc ]
+# [ -sourceversion verno ] [ -include file | -includefuncprefix ]
+# [ -bugsto address ] [ -pkg-name packagename ]
+# [ -seeinfo infonode ] [ -copyright notice ] [ -verbatimcopying ]
+# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
+#
+# Set output format using one of -docbook, -html, -text, -man, -tex,
+# -texinfo, or -listfunc. Default is man.
+#
+# -sourceversion
+# Version number for source code, e.g. '1.0.4'. Used in 'man' headers.
+# Defaults to using current date.
+#
+# -include FILE
+# For man pages, mention #include <FILE.h> in the synopsis.
+#
+# -includefuncprefix
+# For man pages, mention a #include <FILE.h> in the synopsis.
+# The FILE derived from the function prefix. For example, a
+# function gss_init_sec_context will generate an include
+# statement of #include <gss.h>.
+#
+# -bugsto address
+# For man pages, include a section about reporting bugs and mention
+# the given e-mail address, e.g 'bug-libidn@gnu.org'.
+#
+# -pkg-name packagename
+# For man pages when -bugsto is used, also include help URLs to the
+# the project's home page. For example, "GNU Libidn".
+#
+# -seeinfo infonode
+# For man pages, include a section that point to an info manual
+# for more information.
+#
+# -copyright notice
+# For man pages, include a copyright section with the given
+# notice after a preamble. Use, e.g., '2002, 2003 Simon Josefsson'.
+#
+# -verbatimcopying
+# For man pages, and when the -copyright parameter is used,
+# add a licensing statement that say verbatim copying is permitted.
+#
+# -function funcname
+# If set, then only generate documentation for the given function(s). All
+# other functions are ignored.
+#
+# c files - list of 'c' files to process
+#
+# All output goes to stdout, with errors to stderr.
+
+#
+# format of comments.
+# In the following table, (...)? signifies optional structure.
+# (...)* signifies 0 or more structure elements
+# /**
+# * function_name(:)? (- short description)?
+# (* @parameterx: (description of parameter x)?)*
+# (* a blank line)?
+# * (Description:)? (Description of function)?
+# * (Section header: (section description)? )*
+# (*)?*/
+#
+# So .. the trivial example would be:
+#
+# /**
+# * my_function
+# **/
+#
+# If the Description: header tag is ommitted, then there must be a blank line
+# after the last parameter specification.
+# e.g.
+# /**
+# * my_function - does my stuff
+# * @my_arg: its mine damnit
+# *
+# * Does my stuff explained.
+# */
+#
+# or, could also use:
+# /**
+# * my_function - does my stuff
+# * @my_arg: its mine damnit
+# * Description: Does my stuff explained.
+# */
+# etc.
+#
+# All descriptions can be multiline, apart from the short function description.
+#
+# All descriptive text is further processed, scanning for the following special
+# patterns, which are highlighted appropriately.
+#
+# 'funcname()' - function
+# '$ENVVAR' - environmental variable OBSOLETE (?)
+# '#struct_name' - name of a structure
+# '@parameter' - name of a parameter
+# '%CONST' - name of a constant.
+
+#
+# Extensions for LaTeX:
+#
+# 1. the symbol '->' will be replaced with a rightarrow
+# 2. x^y with ${x}^{y}$.
+# 3. xxx\: with xxx:
+
+use POSIX qw(strftime);
+
+# match expressions used to find embedded type information
+$type_constant = "\\\%(\\w+)";
+$type_func = "(\\w+\\(\\))";
+$type_param = "\\\@(\\w+)";
+$type_struct = "\\\#(\\w+)";
+$type_env = "(\\\$\\w+)";
+
+
+# Output conversion substitutions.
+# One for each output format
+
+# these work fairly well
+%highlights_html = ( $type_constant, "<i>\$1</i>",
+ $type_func, "<b>\$1</b>",
+ $type_struct, "<i>\$1</i>",
+ $type_param, "<tt><b>\$1</b></tt>" );
+$blankline_html = "<p>";
+
+%highlights_texinfo = ( $type_constant, "\\\@code{\$1}",
+ $type_func, "\\\@code{\$1}",
+ $type_struct, "\\\@code{\$1}",
+ $type_param, "\\\@code{\$1}" );
+$blankline_texinfo = "";
+
+%highlights_tex = ( $type_constant, "{\\\\it \$1}",
+ $type_func, "{\\\\bf \$1}",
+ $type_struct, "{\\\\it \$1}",
+ $type_param, "{\\\\bf \$1}" );
+$blankline_tex = "\\\\";
+
+# sgml, docbook format
+%highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
+ $type_func, "<function>\$1</function>",
+ $type_struct, "<structname>\$1</structname>",
+ $type_env, "<envar>\$1</envar>",
+ $type_param, "<parameter>\$1</parameter>" );
+$blankline_sgml = "</para><para>\n";
+
+# these are pretty rough
+%highlights_man = ( $type_constant, "\\\\fB\$1\\\\fP",
+ $type_func, "\\\\fB\$1\\\\fP",
+ $type_struct, "\\\\fB\$1\\\\fP",
+ $type_param, "\\\\fI\$1\\\\fP" );
+$blankline_man = "";
+
+# text-mode
+%highlights_text = ( $type_constant, "\$1",
+ $type_func, "\$1",
+ $type_struct, "\$1",
+ $type_param, "\$1" );
+$blankline_text = "";
+
+
+sub usage {
+ print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex | -texinfo -listfunc ]\n";
+ print " [ -sourceversion verno ] [ -include file | -includefuncprefix ]\n";
+ print " [ -bugsto address ] [ -seeinfo infonode ] [ -copyright notice]\n";
+ print " [ -verbatimcopying ] [ -pkg-name packagename ]\n";
+ print " [ -function funcname [ -function funcname ...] ]\n";
+ print " c source file(s) > outputfile\n";
+ exit 1;
+}
+
+# read arguments
+if ($#ARGV==-1) {
+ usage();
+}
+
+$verbose = 0;
+$output_mode = "man";
+%highlights = %highlights_man;
+$blankline = $blankline_man;
+$modulename = "API Documentation";
+$sourceversion = strftime "%Y-%m-%d", localtime;
+$function_only = 0;
+while ($ARGV[0] =~ m/^-(.*)/) {
+ $cmd = shift @ARGV;
+ if ($cmd eq "-html") {
+ $output_mode = "html";
+ %highlights = %highlights_html;
+ $blankline = $blankline_html;
+ } elsif ($cmd eq "-man") {
+ $output_mode = "man";
+ %highlights = %highlights_man;
+ $blankline = $blankline_man;
+ } elsif ($cmd eq "-tex") {
+ $output_mode = "tex";
+ %highlights = %highlights_tex;
+ $blankline = $blankline_tex;
+ } elsif ($cmd eq "-texinfo") {
+ $output_mode = "texinfo";
+ %highlights = %highlights_texinfo;
+ $blankline = $blankline_texinfo;
+ } elsif ($cmd eq "-text") {
+ $output_mode = "text";
+ %highlights = %highlights_text;
+ $blankline = $blankline_text;
+ } elsif ($cmd eq "-docbook") {
+ $output_mode = "sgml";
+ %highlights = %highlights_sgml;
+ $blankline = $blankline_sgml;
+ } elsif ($cmd eq "-listfunc") {
+ $output_mode = "listfunc";
+ } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document
+ $modulename = shift @ARGV;
+ } elsif ($cmd eq "-sourceversion") {
+ $sourceversion = shift @ARGV;
+ } elsif ($cmd eq "-include") {
+ $include = shift @ARGV;
+ } elsif ($cmd eq "-includefuncprefix") {
+ $includefuncprefix = 1;
+ } elsif ($cmd eq "-bugsto") {
+ $bugsto = shift @ARGV;
+ } elsif ($cmd eq "-pkg-name") {
+ $pkgname = shift @ARGV;
+ } elsif ($cmd eq "-copyright") {
+ $copyright = shift @ARGV;
+ } elsif ($cmd eq "-verbatimcopying") {
+ $verbatimcopying = 1;
+ } elsif ($cmd eq "-seeinfo") {
+ $seeinfo = shift @ARGV;
+ } elsif ($cmd eq "-function") { # to only output specific functions
+ $function_only = 1;
+ $function = shift @ARGV;
+ $function_table{$function} = 1;
+ } elsif ($cmd eq "-v") {
+ $verbose = 1;
+ } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
+ usage();
+ }
+}
+
+##
+# dumps section contents to arrays/hashes intended for that purpose.
+#
+sub dump_section {
+ my $name = shift @_;
+ my $contents = join "\n", @_;
+
+ if ($name =~ m/$type_constant/) {
+ $name = $1;
+# print STDERR "constant section '$1' = '$contents'\n";
+ $constants{$name} = $contents;
+ } elsif ($name =~ m/$type_param/) {
+# print STDERR "parameter def '$1' = '$contents'\n";
+ $name = $1;
+ $parameters{$name} = $contents;
+ } else {
+# print STDERR "other section '$name' = '$contents'\n";
+ $sections{$name} = $contents;
+ push @sectionlist, $name;
+ }
+}
+
+##
+# output function
+#
+# parameters, a hash.
+# function => "function name"
+# parameterlist => @list of parameters
+# parameters => %parameter descriptions
+# sectionlist => @list of sections
+# sections => %descriont descriptions
+#
+
+sub repstr {
+ $pattern = shift;
+ $repl = shift;
+ $match1 = shift;
+ $match2 = shift;
+ $match3 = shift;
+ $match4 = shift;
+
+ $output = $repl;
+ $output =~ s,\$1,$match1,g;
+ $output =~ s,\$2,$match2,g;
+ $output =~ s,\$3,$match3,g;
+ $output =~ s,\$4,$match4,g;
+
+ eval "\$return = qq/$output/";
+
+# print "pattern $pattern matched 1=$match1 2=$match2 3=$match3 4=$match4 replace $repl yielded $output interpolated $return\n";
+
+ $return;
+}
+
+sub just_highlight {
+ my $contents = join "\n", @_;
+ my $line;
+ my $ret = "";
+
+ foreach $pattern (keys %highlights) {
+# print "scanning pattern $pattern ($highlights{$pattern})\n";
+ $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2, $3, $4):gse;
+ }
+ foreach $line (split "\n", $contents) {
+ if ($line eq ""){
+ $ret = $ret . $lineprefix . $blankline;
+ } else {
+ $ret = $ret . $lineprefix . $line;
+ }
+ $ret = $ret . "\n";
+ }
+
+ return $ret;
+}
+
+sub output_highlight {
+ print (just_highlight (@_));
+}
+
+# output in texinfo
+sub output_texinfo {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ print "\@subheading ".$args{'function'}."\n";
+ print "\@anchor{".$args{'function'}."}\n";
+ print "\@deftypefun {" . $args{'functiontype'} . "} ";
+ print "{".$args{'function'}."} ";
+ print "(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print $args{'parametertypes'}{$parameter}." \@var{".$parameter."}";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ")\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ if ($args{'parameters'}{$parameter}) {
+ print "\@var{".$parameter."}: ";
+ output_highlight($args{'parameters'}{$parameter});
+ print "\n";
+ }
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "\n\@strong{$section:} " if $section ne $section_default;
+ $args{'sections'}{$section} =~ s:([{}]):\@\1:gs;
+ output_highlight($args{'sections'}{$section});
+ }
+ print "\@end deftypefun\n\n";
+}
+
+# output in html
+sub output_html {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ print "\n\n<a name=\"". $args{'function'} . "\">&nbsp</a><h2>Function</h2>\n";
+
+ print "<i>".$args{'functiontype'}."</i>\n";
+ print "<b>".$args{'function'}."</b>\n";
+ print "(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ")\n";
+
+ print "<h3>Arguments</h3>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter."</b>\n";
+ print "<dd>";
+ output_highlight($args{'parameters'}{$parameter});
+ }
+ print "</dl>\n";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<h3>$section</h3>\n";
+ print "<ul>\n";
+ output_highlight($args{'sections'}{$section});
+ print "</ul>\n";
+ }
+ print "<hr>\n";
+}
+
+# output in tex
+sub output_tex {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $func = $args{'function'};
+ my $param;
+ my $param2;
+ my $sec;
+ my $check;
+ my $type;
+
+ $func =~ s/_/\\_/g;
+
+ print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\n";
+
+ $type = $args{'functiontype'};
+ $type =~ s/_/\\_/g;
+
+ print "{\\it ".$type."}\n";
+ print "{\\bf ".$func."}\n";
+ print "(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ $param = $args{'parametertypes'}{$parameter};
+ $param2 = $parameter;
+ $param =~ s/_/\\_/g;
+ $param2 =~ s/_/\\_/g;
+
+ print "{\\it ".$param."} {\\bf ".$param2."}";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ")\n";
+
+ print "\n{\\large{Arguments}}\n";
+
+ print "\\begin{itemize}\n";
+ $check=0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ $param1 = $args{'parametertypes'}{$parameter};
+ $param1 =~ s/_/\\_/g;
+ $param2 = $parameter;
+ $param2 =~ s/_/\\_/g;
+
+ $check = 1;
+ print "\\item {\\it ".$param1."} {\\bf ".$param2."}: \n";
+# print "\n";
+
+ $param3 = $args{'parameters'}{$parameter};
+ $param3 =~ s/#([a-zA-Z\_]+)/{\\it \1}/g;
+
+ $out = just_highlight($param3);
+ $out =~ s/_/\\_/g;
+ print $out;
+ }
+ if ($check==0) {
+ print "\\item void\n";
+ }
+ print "\\end{itemize}\n";
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ $sec = $section;
+ $sec =~ s/_/\\_/g;
+ $sec =~ s/#([a-zA-Z\_]+)/{\\it \1}/g;
+
+ print "\n{\\large{$sec}}\\\\\n";
+ print "\\begin{rmfamily}\n";
+
+ $sec = $args{'sections'}{$section};
+ $sec =~ s/\\:/:/g;
+ $sec =~ s/#([a-zA-Z\_]+)/{\\it \1}/g;
+ $sec =~ s/->/\$\\rightarrow\$/g;
+ $sec =~ s/([0-9]+)\^([0-9]+)/\$\{\1\}\^\{\2\}\$/g;
+
+ $out = just_highlight($sec);
+ $out =~ s/_/\\_/g;
+
+ print $out;
+ print "\\end{rmfamily}\n";
+ }
+ print "\n";
+}
+
+
+# output in sgml DocBook
+sub output_sgml {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $id;
+
+ $id = $args{'module'}."-".$args{'function'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ print "<refentry>\n";
+ print "<refmeta>\n";
+ print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
+ print "</refmeta>\n";
+ print "<refnamediv>\n";
+ print " <refname>".$args{'function'}."</refname>\n";
+ print " <refpurpose>\n";
+ print " ".$args{'purpose'}."\n";
+ print " </refpurpose>\n";
+ print "</refnamediv>\n";
+
+ print "<refsynopsisdiv>\n";
+ print " <title>Synopsis</title>\n";
+ print " <funcsynopsis>\n";
+ print " <funcdef>".$args{'functiontype'}." ";
+ print "<function>".$args{'function'}." ";
+ print "</function></funcdef>\n";
+
+# print "<refsect1>\n";
+# print " <title>Synopsis</title>\n";
+# print " <funcsynopsis>\n";
+# print " <funcdef>".$args{'functiontype'}." ";
+# print "<function>".$args{'function'}." ";
+# print "</function></funcdef>\n";
+
+ $count = 0;
+ if ($#{$args{'parameterlist'}} >= 0) {
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " <paramdef>".$args{'parametertypes'}{$parameter};
+ print " <parameter>$parameter</parameter></paramdef>\n";
+ }
+ } else {
+ print " <void>\n";
+ }
+ print " </funcsynopsis>\n";
+ print "</refsynopsisdiv>\n";
+# print "</refsect1>\n";
+
+ # print parameters
+ print "<refsect1>\n <title>Arguments</title>\n";
+# print "<para>\nArguments\n";
+ if ($#{$args{'parameterlist'}} >= 0) {
+ print " <variablelist>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n";
+ print " <listitem>\n <para>\n";
+ $lineprefix=" ";
+ output_highlight($args{'parameters'}{$parameter});
+ print " </para>\n </listitem>\n </varlistentry>\n";
+ }
+ print " </variablelist>\n";
+ } else {
+ print " <para>\n None\n </para>\n";
+ }
+ print "</refsect1>\n";
+
+ # print out each section
+ $lineprefix=" ";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<refsect1>\n <title>$section</title>\n <para>\n";
+# print "<para>\n$section\n";
+ if ($section =~ m/EXAMPLE/i) {
+ print "<example><para>\n";
+ }
+ output_highlight($args{'sections'}{$section});
+# print "</para>";
+ if ($section =~ m/EXAMPLE/i) {
+ print "</para></example>\n";
+ }
+ print " </para>\n</refsect1>\n";
+ }
+
+ print "\n\n";
+}
+
+##
+# output in man
+sub output_man {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ print ".\\\" DO NOT MODIFY THIS FILE! It was generated by gdoc.\n";
+ print ".TH \"$args{'function'}\" 3 \"$args{'sourceversion'}\" \"". $args{'module'} . "\" \"". $args{'module'} . "\"\n";
+
+ print ".SH NAME\n";
+
+ print $args{'function'};
+ if ($args{'purpose'}) {
+ print " \\- " . $args{'purpose'} . "\n";
+ } else {
+ print " \\- API function\n";
+ }
+
+ print ".SH SYNOPSIS\n";
+ print ".B #include <". $args{'include'} . ">\n"
+ if $args{'include'};
+ print ".B #include <". lc((split /_/, $args{'function'})[0]) . ".h>\n"
+ if $args{'includefuncprefix'};
+ print ".sp\n";
+ print ".BI \"".$args{'functiontype'}." ".$args{'function'}."(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print $args{'parametertypes'}{$parameter}." \" ".$parameter." \"";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ");\"\n";
+
+ print ".SH ARGUMENTS\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\" 12\n";
+ $param = $args{'parameters'}{$parameter};
+ $param =~ s/-/\\-/g;
+ output_highlight($param);
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print ".SH \"" . uc($section) . "\"\n";
+ $sec = $args{'sections'}{$section};
+ $sec =~ s/-/\\-/g;
+ output_highlight($sec);
+ }
+
+ if ($args{'bugsto'}) {
+ print ".SH \"REPORTING BUGS\"\n";
+ print "Report bugs to <". $args{'bugsto'} . ">.\n";
+ if ($args{'pkgname'}) {
+ print $args{'pkgname'} . " home page: " .
+ "http://www.gnu.org/software/" . $args{'module'} . "/\n";
+ }
+ print "General help using GNU software: http://www.gnu.org/gethelp/\n";
+ }
+
+ if ($args{'copyright'}) {
+ print ".SH COPYRIGHT\n";
+ print "Copyright \\(co ". $args{'copyright'} . ".\n";
+ if ($args{'verbatimcopying'}) {
+ print ".br\n";
+ print "Copying and distribution of this file, with or without modification,\n";
+ print "are permitted in any medium without royalty provided the copyright\n";
+ print "notice and this notice are preserved.\n";
+ }
+ }
+
+ if ($args{'seeinfo'}) {
+ print ".SH \"SEE ALSO\"\n";
+ print "The full documentation for\n";
+ print ".B " . $args{'module'} . "\n";
+ print "is maintained as a Texinfo manual. If the\n";
+ print ".B info\n";
+ print "and\n";
+ print ".B " . $args{'module'} . "\n";
+ print "programs are properly installed at your site, the command\n";
+ print ".IP\n";
+ print ".B info " . $args{'seeinfo'} . "\n";
+ print ".PP\n";
+ print "should give you access to the complete manual.\n";
+ }
+}
+
+sub output_listfunc {
+ my %args = %{$_[0]};
+ print $args{'function'} . "\n";
+}
+
+##
+# output in text
+sub output_text {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+
+ print "Function = ".$args{'function'}."\n";
+ print " return type: ".$args{'functiontype'}."\n\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n";
+ print " -> ".$args{'parameters'}{$parameter}."\n";
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print " $section:\n";
+ print " -> ";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+##
+# generic output function - calls the right one based
+# on current output mode.
+sub output_function {
+# output_html(@_);
+ eval "output_".$output_mode."(\@_);";
+}
+
+
+##
+# takes a function prototype and spits out all the details
+# stored in the global arrays/hsahes.
+sub dump_function {
+ my $prototype = shift @_;
+
+ if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/) {
+ $return_type = $1;
+ $function_name = $2;
+ $args = $3;
+
+# print STDERR "ARGS = '$args'\n";
+
+ foreach $arg (split ',', $args) {
+ # strip leading/trailing spaces
+ $arg =~ s/^\s*//;
+ $arg =~ s/\s*$//;
+# print STDERR "SCAN ARG: '$arg'\n";
+ @args = split('\s', $arg);
+
+# print STDERR " -> @args\n";
+ $param = pop @args;
+# print STDERR " -> @args\n";
+ if ($param =~ m/^(\*+)(.*)/) {
+ $param = $2;
+ push @args, $1;
+ }
+ if ($param =~ m/^(.*)(\[\])$/) {
+ $param = $1;
+ push @args, $2;
+ }
+# print STDERR " :> @args\n";
+ $type = join " ", @args;
+
+ if ($parameters{$param} eq "" && $param != "void") {
+ $parameters{$param} = "-- undescribed --";
+ print STDERR "warning: $lineno: Function parameter '$param' not described in '$function_name'\n";
+ }
+
+ push @parameterlist, $param;
+ $parametertypes{$param} = $type;
+
+# print STDERR "param = '$param', type = '$type'\n";
+ }
+ } else {
+ print STDERR "warning: $lineno: Cannot understand prototype: '$prototype'\n" if (!($prototype =~ m,GSASL_VALID_MECHANISM_CHARACTERS,));
+ return;
+ }
+
+ if ($function_only==0 || defined($function_table{$function_name})) {
+ output_function({'function' => $function_name,
+ 'module' => $modulename,
+ 'sourceversion' => $sourceversion,
+ 'include' => $include,
+ 'includefuncprefix' => $includefuncprefix,
+ 'bugsto' => $bugsto,
+ 'pkgname' => $pkgname,
+ 'copyright' => $copyright,
+ 'verbatimcopying' => $verbatimcopying,
+ 'seeinfo' => $seeinfo,
+ 'functiontype' => $return_type,
+ 'parameterlist' => \@parameterlist,
+ 'parameters' => \%parameters,
+ 'parametertypes' => \%parametertypes,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $function_purpose
+ });
+ }
+}
+
+######################################################################
+# main
+# states
+# 0 - normal code
+# 1 - looking for function name
+# 2 - scanning field start.
+# 3 - scanning prototype.
+$state = 0;
+$section = "";
+
+$doc_special = "\@\%\$\#";
+
+$doc_start = "^/\\*\\*\$";
+$doc_end = "\\*/";
+$doc_com = "\\s*\\*\\s*";
+$doc_func = $doc_com."(\\w+):?";
+$doc_sect = $doc_com."([".$doc_special."[:upper:]][\\w ]+):\\s*(.*)";
+$doc_content = $doc_com."(.*)";
+
+%constants = ();
+%parameters = ();
+@parameterlist = ();
+%sections = ();
+@sectionlist = ();
+
+$contents = "";
+$section_default = "Description"; # default section
+$section = $section_default;
+
+$lineno = 0;
+foreach $file (@ARGV) {
+ if (!open(IN,"<$file")) {
+ print STDERR "Error: Cannot open file $file\n";
+ next;
+ }
+ while (<IN>) {
+ $lineno++;
+
+ if ($state == 0) {
+ if (/$doc_start/o) {
+ $state = 1; # next line is always the function name
+ }
+ } elsif ($state == 1) { # this line is the function name (always)
+ if (/$doc_func/o) {
+ $function = $1;
+ $state = 2;
+ if (/-\s*(.*)/) {
+ $function_purpose = $1;
+ } else {
+ $function_purpose = "";
+ }
+ if ($verbose) {
+ print STDERR "Info($lineno): Scanning doc for $function\n";
+ }
+ } else {
+ print STDERR "warning: $lineno: Cannot understand $_ on line $lineno",
+ " - I thought it was a doc line\n";
+ $state = 0;
+ }
+ } elsif ($state == 2) { # look for head: lines, and include content
+ if (/$doc_sect/o) {
+ $newsection = $1;
+ $newcontents = $2;
+
+ if ($contents ne "") {
+ dump_section($section, $contents);
+ $section = $section_default;
+ }
+
+ $contents = $newcontents;
+ if ($contents ne "") {
+ $contents .= "\n";
+ }
+ $section = $newsection;
+ } elsif (/$doc_end/) {
+
+ if ($contents ne "") {
+ dump_section($section, $contents);
+ $section = $section_default;
+ $contents = "";
+ }
+
+# print STDERR "end of doc comment, looking for prototype\n";
+ $prototype = "";
+ $state = 3;
+ } elsif (/$doc_content/) {
+ # miguel-style comment kludge, look for blank lines after
+ # @parameter line to signify start of description
+ if ($1 eq "" && $section =~ m/^@/) {
+ dump_section($section, $contents);
+ $section = $section_default;
+ $contents = "";
+ } else {
+ $contents .= $1."\n";
+ }
+ } else {
+ # i dont know - bad line? ignore.
+ print STDERR "warning: $lineno: Bad line: $_";
+ }
+ } elsif ($state == 3) { # scanning for function { (end of prototype)
+ if (m#\s*/\*\s+MACDOC\s*#io) {
+ # do nothing
+ }
+ elsif (/([^\{]*)/) {
+ $prototype .= $1;
+ }
+ if (/\{/) {
+ $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
+ $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
+ $prototype =~ s@^ +@@gos; # strip leading spaces
+ dump_function($prototype);
+
+ $function = "";
+ %constants = ();
+ %parameters = ();
+ %parametertypes = ();
+ @parameterlist = ();
+ %sections = ();
+ @sectionlist = ();
+ $prototype = "";
+
+ $state = 0;
+ }
+ }
+ }
+}
diff --git a/contrib/gen-dir-node b/contrib/gen-dir-node
new file mode 100755
index 0000000..7b4bc02
--- /dev/null
+++ b/contrib/gen-dir-node
@@ -0,0 +1,211 @@
+#!/bin/sh
+# Generate the top-level Info node, given a directory of Info files
+# and (optionally) a skeleton file. The output will be suitable for a
+# top-level dir file. The skeleton file contains info topic names in the
+# order they should appear in the output. There are three special
+# lines that alter the behavior: a line consisting of just "--" causes
+# the next line to be echoed verbatim to the output. A line
+# containing just "%%" causes all the remaining filenames (wildcards
+# allowed) in the rest of the file to be ignored. A line containing
+# just "!!" exits the script when reached (unless preceded by a line
+# containing just "--"). Once the script reaches the end of the
+# skeleton file, it goes through the remaining files in the directory
+# in order, putting their entries at the end. The script will use the
+# ENTRY information in each info file if it exists. Otherwise it will
+# make a minimal entry.
+
+# sent by Jeffrey Osier <jeffrey@cygnus.com>, who thinks it came from
+# zoo@winternet.com (david d `zoo' zuhn)
+
+# modified 7 April 1995 by Joe Harrington <jh@tecate.gsfc.nasa.gov> to
+# take special flags
+
+INFODIR=$1
+if [ $# = 2 ] ; then
+ SKELETON=$2
+else
+ SKELETON=/dev/null
+fi
+
+skip=
+
+if [ $# -gt 2 ] ; then
+ echo usage: $0 info-directory [ skeleton-file ] 1>&2
+ exit 1
+elif [ -z "${INFODIR}" ] ; then
+ INFODIR="%%DEFAULT_INFO_DIR%%"
+else
+ true
+fi
+
+if [ ! -d ${INFODIR} ] ; then
+ echo "$0: first argument must specify a directory"
+ exit 1
+fi
+
+### output the dir header
+echo "-*- Text -*-"
+echo "This file was generated automatically by $0."
+echo "This version was generated on `date`"
+echo "by `whoami`@`hostname` for `(cd ${INFODIR}; pwd)`"
+
+cat << moobler
+\$Id: gen-dir-node,v 1.1 2013-01-02 01:00:25 karl Exp $
+This is the file .../info/dir, which contains the topmost node of the
+Info hierarchy. The first time you invoke Info you start off
+looking at that node, which is (dir)Top.
+
+File: dir Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs topic, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu: The list of major topics begins on the next line.
+
+moobler
+
+### go through the list of files in the skeleton. If an info file
+### exists, grab the ENTRY information from it. If an entry exists
+### use it, otherwise create a minimal dir entry.
+###
+### Then remove that file from the list of existing files. If any
+### additional files remain (ones that don't have a skeleton entry),
+### then generate entries for those in the same way, putting the info for
+### those at the end....
+
+infofiles=`(cd ${INFODIR}; /bin/ls | grep -v '\-[0-9]*$' | egrep -v '^dir$|^dir\.info$|^dir\.orig$')`
+
+# echoing gets clobbered by backquotes; we do it the hard way...
+lines=`wc $SKELETON | awk '{print $1}'`
+line=1
+while [ $lines -ge $line ] ; do
+ # Read one line from the file. This is so that we can echo lines with
+ # whitespace and quoted characters in them.
+ fileline=`awk NR==$line $SKELETON`
+
+ # flag fancy features
+ if [ ! -z "$echoline" ] ; then # echo line
+ echo "$fileline"
+ fileline=
+ echoline=
+ elif [ "${fileline}" = "--" ] ; then # should we echo the next line?
+ echoline=1
+ elif [ "${fileline}" = "%%" ] ; then # eliminate remaining files from dir?
+ skip=1
+ elif [ "${fileline}" = "!!" ] ; then # quit now
+ exit 0
+ fi
+
+ # handle files if they exist
+ for file in $fileline"" ; do # expand wildcards ("" handles blank lines)
+
+ fname=
+
+ if [ -z "$echoline" ] && [ ! -z "$file" ] ; then
+ # Find the file to operate upon. Check both possible names.
+ infoname=`echo $file | sed 's/\.info$//'`
+ noext=
+ ext=
+ if [ -f ${INFODIR}/$infoname ] ; then
+ noext=$infoname
+ fi
+ if [ -f ${INFODIR}/${infoname}.info ] ; then
+ ext=${infoname}.info
+ fi
+
+ # If it exists with both names take what was said in the file.
+ if [ ! -z "$ext" ] && [ ! -z "$noext" ]; then
+ fname=$file
+ warn="### Warning: $ext and $noext both exist! Using ${file}. ###"
+ elif [ ! -z "${noext}${ext}" ]; then
+ # just take the name if it exists only once
+ fname=${noext}${ext}
+ fi
+
+ # if we found something and aren't skipping, do the entry
+ if [ ! -z "$fname" ] ; then
+ if [ -z "$skip" ] ; then
+
+ if [ ! -z "$warn" ] ; then # issue any warning
+ echo $warn
+ warn=
+ fi
+
+ entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \
+ -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/$fname`
+ if [ ! -z "${entry}" ] ; then
+ echo "${entry}"
+ else
+ echo "* ${infoname}: (${infoname})."
+ fi
+ fi
+
+ # remove the name from the directory listing
+ infofiles=`echo "" ${infofiles} "" | sed -e "s/ ${fname} / /" -e "s/ / /g"`
+
+ fi
+
+ fi
+
+ done
+
+ line=`expr $line + 1`
+done
+
+if [ -z "${infofiles}" ] ; then
+ exit 0
+elif [ $lines -gt 0 ]; then
+ echo
+fi
+
+# Sort remaining files by INFO-DIR-SECTION.
+prevsect=
+filesectdata=`(cd ${INFODIR}; fgrep INFO-DIR-SECTION /dev/null ${infofiles} | \
+ fgrep -v 'INFO-DIR-SECTION Miscellaneous' | \
+ sort -t: -k2 -k1 | tr ' ' '_')`
+for sectdata in ${filesectdata}; do
+ file=`echo ${sectdata} | cut -d: -f1`
+ section=`sed -n -e 's/^INFO-DIR-SECTION //p' ${INFODIR}/${file}`
+ infofiles=`echo "" ${infofiles} "" | sed -e "s/ ${file} / /" -e "s/ / /g"`
+
+ if [ "${prevsect}" != "${section}" ] ; then
+ if [ ! -z "${prevsect}" ] ; then
+ echo ""
+ fi
+ echo "${section}"
+ prevsect="${section}"
+ fi
+
+ infoname=`echo $file | sed 's/\.info$//'`
+ entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \
+ -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}`
+ if [ ! -z "${entry}" ] ; then
+ echo "${entry}"
+ elif [ ! -d "${INFODIR}/${file}" ] ; then
+ echo "* ${infoname}: (${infoname})."
+ fi
+done
+
+# Process miscellaneous files.
+for file in ${infofiles}; do
+ if [ ! -z "${prevsect}" ] ; then
+ echo ""
+ echo "Miscellaneous"
+ prevsect=""
+ fi
+
+ infoname=`echo $file | sed 's/\.info$//'`
+ entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \
+ -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}`
+
+ if [ ! -z "${entry}" ] ; then
+ echo "${entry}"
+ elif [ ! -d "${INFODIR}/${file}" ] ; then
+ echo "* ${infoname}: (${infoname})."
+ fi
+done
diff --git a/contrib/infosrch b/contrib/infosrch
new file mode 100755
index 0000000..c9f64b4
--- /dev/null
+++ b/contrib/infosrch
@@ -0,0 +1,103 @@
+#!/usr/local/bin/perl -w
+# infosrch does a regex search on an info manual.
+# By Harry Putnam <reader@newsguy.com>.
+
+($myscript = $0) =~ s:^.*/::;
+$six = '';
+
+if($ARGV[0] eq "help"){
+ &usage;
+ exit;
+}
+if($ARGV[0] eq "-e"){
+ shift;
+ $six = "true";
+}
+if(!$ARGV[1]){
+ &usage;
+ exit;
+}
+
+$target = shift;
+$regex = shift;
+
+$shell_proc = "info --output - --subnodes 2>/dev/null $target";
+
+open(SHELL_PROC," $shell_proc|");
+while(<SHELL_PROC>){
+ chomp;
+ push @lines,$_;
+}
+close(SHELL_PROC);
+$cnt = 0;
+for(@lines){
+ if(/$regex/ && !$six){
+ print "$target\n $lines[($cnt-1)]\n<$cnt> $lines[$cnt]\n $lines[($cnt+1)]\n";
+ print "-- \n";
+ }elsif(/$regex/ && $six){
+ print "$target\n";
+ if($lines[($cnt-6)]){
+ print " $lines[($cnt-6)]\n";
+ }
+ if($lines[($cnt-5)]){
+ print " $lines[($cnt-5)]\n";
+ }
+ if($lines[($cnt-4)]){
+ print " $lines[($cnt-4)]\n";
+ }
+ if($lines[($cnt-3)]){
+ print " $lines[($cnt-3)]\n";
+ }
+ if($lines[($cnt-2)]){
+ print " $lines[($cnt-2)]\n";
+ }
+ if($lines[($cnt-1)]){
+ print " $lines[($cnt-1)]\n";
+ }
+ if($lines[$cnt]){
+ print "$cnt $lines[$cnt]\n";
+ }
+ if($lines[($cnt+1)]){
+ print " $lines[($cnt+1)]\n";
+ }
+ if($lines[($cnt+2)]){
+ print " $lines[($cnt+2)]\n";
+ }
+ if($lines[($cnt+3)]){
+ print " $lines[($cnt+3)]\n";
+ }
+ if($lines[($cnt+4)]){
+ print " $lines[($cnt+4)]\n";
+ }
+ if($lines[($cnt+5)]){
+ print " $lines[($cnt+5)]\n";
+ }
+ if($lines[($cnt+6)]){
+ print " $lines[($cnt+6)]\n";
+ }
+ print "-- \n";
+ }
+ $cnt++;
+}
+
+sub usage {
+ print <<EOM;
+
+Purpose: Extract full text from info node and search it by regex
+Usage: $myscript [-e] TARGET REGEX
+
+Where TARGET is an info node such as `emacs', `bash' etc, and
+REGEX is what you want to find in it.
+
+The -e flag is not required but if used then 6 lines preceding and six
+lines following any hits will be printed. The default (with no -e flag)
+is to print one line before and after.
+
+The output has the line number prepended to the line containing the
+actual regex.
+
+Info command used:
+ info --output - --subnodes 2>/dev/null TARGET
+
+EOM
+}
diff --git a/contrib/javaprop2texiflag.pl b/contrib/javaprop2texiflag.pl
new file mode 100644
index 0000000..4e6f22a
--- /dev/null
+++ b/contrib/javaprop2texiflag.pl
@@ -0,0 +1,297 @@
+#!/usr/bin/env perl
+# javaprop2texiflag.pl --- -*- coding: utf-8 -*-
+# Copyright 2012 Vincent Belaïche
+#
+# Author: Vincent Belaïche <vincentb1@users.sourceforge.net>
+# Version: $Id: javaprop2texiflag.pl,v 1.2 2012/09/02 11:17:29 vincentb1 Exp $
+# Keywords:
+# X-URL: http://www.jpicedt.org/
+#
+# Ce logiciel est régi par la licence CeCILL soumise au droit français et respectant les principes de
+# diffusion des logiciels libres. Vous pouvez utiliser, modifier et/ou redistribuer ce programme sous les
+# conditions de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA sur le site
+# "http://www.cecill.info".
+#
+# En contrepartie de l'accessibilité au code source et des droits de copie, de modification et de
+# redistribution accordés par cette licence, il n'est offert aux utilisateurs qu'une garantie limitée. Pour
+# les mêmes raisons, seule une responsabilité restreinte pèse sur l'auteur du programme, le titulaire des
+# droits patrimoniaux et les concédants successifs.
+#
+# A cet égard l'attention de l'utilisateur est attirée sur les risques associés au chargement, à
+# l'utilisation, à la modification et/ou au développement et à la reproduction du logiciel par l'utilisateur
+# étant donné sa spécificité de logiciel libre, qui peut le rendre complexe à manipuler et qui le réserve donc
+# à des développeurs et des professionnels avertis possédant des connaissances informatiques approfondies.
+# Les utilisateurs sont donc invités à charger et tester l'adéquation du logiciel à leurs besoins dans des
+# conditions permettant d'assurer la sécurité de leurs systèmes et ou de leurs données et, plus généralement,
+# à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
+#
+# Le fait que vous puissiez accéder à cet en-tête signifie que vous avez pris connaissance de la licence
+# CeCILL, et que vous en avez accepté les termes.
+#
+## Commentary:
+
+#
+
+## Installation:
+
+## Code:
+use strict;
+use warnings;
+use feature qw(say unicode_strings);
+use PerlIO;
+
+my $version='$Id: javaprop2texiflag.pl,v 1.2 2012/09/02 11:17:29 vincentb1 Exp $';
+my $linenb = 0;
+my $inputfile;
+my $verbose;
+
+
+sub usage
+{
+ my $retval = shift;
+ print "Usage:
+ javaprop2texiflag.pl ARGUMENTS LIST
+
+-h, --header ARG : Add a header ARG to the produced output
+-p, --prefix ARG : Set prefix to ARG, prefix is empty by default
+-i, --input ARG : Set input to ARG, otherwise it is STDIN
+-i, --output ARG : Set output to ARG, otherwise it is STDIN
+-c, --showcomments : Translate comments into the output
+-e, --showemptylines: Translate empty lines into the output
+-v, --verbose : Output some message when done
+--version : show version and exit
+--help : show this message and exit
+";
+ exit $retval;
+}
+
+#
+#
+sub jp2texif_unescape
+{
+ $_ = shift();
+ s!\\(n(?{"\n"})|r(?{"\r"})|f(?{"\f"})|t(?{"\t"})|u([0-9A-F]{4})(?{chr hex $2})|(.)(?{$3}))!$^R!g;
+ return $_;
+}
+
+sub jp2texif_encode
+{
+ $_ = shift;
+ s!(([\@\{\}])(?{'@'."$2"})|\n(?{'@*'}))!$^R!g;
+ # Texinfo-fier les espaces de tête pour les rendre significatifs
+ if(/\A([ \t]+)(.*)\Z/)
+ {
+ my $spaceprefix = $1;
+ my $remainder = $2;
+ $spaceprefix =~ s!(.)!\@$1!g;
+ $_ = $spaceprefix . $remainder;
+ }
+ # Texinfo-fier les espaces de queue pour les rendre significatifs
+ if(/(.+?)([ \t]+)\Z/)
+ {
+ my $spacepostfix = $2;
+ my $remainder = $1;
+ $spacepostfix =~ s!(.)!\@$1!g;
+ $_ = $remainder . $spacepostfix;
+ }
+ return $_
+}
+
+my @header = ();
+my $prefix = "";
+my $outputfile;
+my $showcomments;
+my $showemptylines;
+
+my $i = 0;
+while($i < @ARGV){
+ if($i + 1 < @ARGV)
+ {
+ if($ARGV[$i] =~ /\A-(i|-input)\Z/)
+ {
+ $inputfile = $ARGV[$i+1];
+ $i = $i +2;
+ }
+ elsif($ARGV[$i] =~ /\A-(o|-output)\Z/)
+ {
+ $outputfile = $ARGV[$i+1];
+ $i = $i +2;
+ }
+ elsif($ARGV[$i] =~ /\A-(p|-prefix)\Z/)
+ {
+ $prefix = $ARGV[$i+1];
+ $i = $i +2;
+ }
+ elsif($ARGV[$i] =~ /\A-(h|-header)\Z/)
+ {
+ $header[++$#header] = \$ARGV[$i+1];
+ $i = $i +2;
+ }
+ else
+ {
+ goto ONE_ARG;
+ }
+ }
+ else
+ {
+ ONE_ARG:
+ {
+ if($ARGV[$i] =~ /\A-(c|-showcomments)\Z/)
+ {
+ $showcomments = 1;
+ $i ++;
+ }
+ elsif($ARGV[$i] =~ /\A-(e|-showemptylines)\Z/)
+ {
+ $showemptylines = 1;
+ $i ++;
+ }
+ elsif($ARGV[$i] =~ /\A-(v|-verbose)\Z/)
+ {
+ $verbose = 1;
+ $i ++;
+ }
+ elsif($ARGV[$i] eq "--version")
+ {
+ print "Version of javaprop2texiflag.pl = $version\n";
+ exit 0;
+ }
+ elsif($ARGV[$i] eq "--help")
+ {
+ usage(0);
+ exit;
+ }
+ else
+ {
+ print "Invalid remaining arguments: @ARGV[$i .. $#ARGV]\n";
+ usage(-1);
+ }
+ }
+ }
+}
+
+my $in;
+if($inputfile)
+{
+ open($in, "< :encoding(ISO-8859-1)", $inputfile) or die "Can't open $inputfile $!";
+}
+else
+{
+ $in = \*STDIN;
+}
+my $out;
+if($outputfile)
+{
+ open($out, "> :encoding(UTF-8)", $outputfile) or die "Can't open $outputfile $!";
+}
+else
+{
+ $out = \*STDOUT;
+}
+select $out;
+
+my $line;
+if(@header)
+{
+ foreach(@header){
+ say '@c ', $$_;
+ }
+}
+
+my $folded_line = 0;
+my $flagnb = 0;
+
+my $propname;
+my $propval;
+my $nextpropval;
+
+LINE: while(<$in>){
+ $line = $_ ;
+ $linenb++ ;
+ if($line =~ /\A(\s*)[#!](.*)\Z/)
+ {
+ if($showcomments)
+ {
+ say "$1" , '@c ' , "$2";
+ }
+ next LINE;
+ }
+ elsif($line =~ /\A\s*\Z/)
+ {
+ if($showemptylines)
+ {
+ say "\n";
+ }
+ next LINE;
+ }
+ elsif($line =~ /\A(\s*(.*))\Z/)
+ {
+ if($folded_line == 0)
+ {
+ if($line =~ /\A\s*((?:[a-zA-Z0-9_\.-]|\\[nr=:])+)\s*[=:](.*)\Z/)
+ {
+ $propname = $1;
+ $propval = $2;
+ if($propval =~ m!(\\+)$! && (length($1) & 1) == 1)
+ {
+ # nombre impair de contre-obliques en fin de ligne, c'est un repliement
+ $folded_line = 1;
+ $propval =~ s!.$!!;
+ $propval = jp2texif_unescape($propval);
+
+ }
+ else
+ {
+ say "\@set $prefix$propname " , jp2texif_encode( jp2texif_unescape($propval));
+ $flagnb ++;
+ }
+ }
+ else
+ {
+ die "$inputfile:$linenb: Invalid line = $line";
+ }
+ }
+ elsif($folded_line == 1)
+ {
+ $nextpropval = $2;
+ if($nextpropval =~ m!(\\+)$! && (length($1) & 1) == 1)
+ {
+ # nombre impair de contre-obliques en fin de ligne, on reste en repliement
+ $nextpropval =~ s!.$!!;
+ $propval = $propval . jp2texif_unescape($nextpropval);
+ }
+ else
+ {
+ # le repliement est fini
+ $folded_line = 0;
+ $propval = $propval . jp2texif_unescape($nextpropval);
+ say "\@set $prefix$propname " , jp2texif_encode($propval);
+ $flagnb ++;
+ }
+
+ }
+ else
+ {
+ die "$inputfile:$linenb: javaprop2texiflag INTERNAL BUG";
+ }
+
+ next LINE;
+ }
+ else
+ {
+ die "$inputfile:$linenb: Invalid line = $line";
+ }
+}
+
+if($verbose)
+{
+ if($inputfile)
+ {
+ $inputfile = "file \`$inputfile\'";
+ }
+ else
+ {
+ $inputfile = "standard input";
+ }
+ print STDOUT "\nDone: javaprop2texiflag is finished,\n\tinput was $inputfile,\n\t$linenb lines were processed,\n\t$flagnb flags were produced.\n";
+}
diff --git a/contrib/outline.gawk b/contrib/outline.gawk
new file mode 100644
index 0000000..fa67263
--- /dev/null
+++ b/contrib/outline.gawk
@@ -0,0 +1,144 @@
+#! /usr/local/bin/gawk -f
+
+# texi.outline --- produce an outline from a texinfo source file
+#
+# Copyright (C) 1998 Arnold David Robbins (arnold@gnu.org)
+#
+# TEXI.OUTLINE 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 3 of the License, or
+# (at your option) any later version.
+#
+# TEXI.OUTLINE is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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, see <http://www.gnu.org/licenses/>.
+
+# NOTE:
+# This program uses gensub(), which is specific to gawk.
+# With some work (split, substr, etc), it could be made to work
+# on other awks, but it's not worth the trouble for me.
+
+BEGIN \
+{
+ # Levels at which different nodes can be
+ Level["@top"] = 0
+ Level["@appendix"] = 1
+ Level["@chapter"] = 1
+ Level["@majorheading"] = 1
+ Level["@unnumbered"] = 1
+ Level["@appendixsec"] = 2
+ Level["@heading"] = 2
+ Level["@section"] = 2
+ Level["@unnumberedsec"] = 2
+ Level["@unnumberedsubsec"] = 3
+ Level["@appendixsubsec"] = 3
+ Level["@subheading"] = 3
+ Level["@subsection"] = 3
+ Level["@appendixsubsubsec"] = 4
+ Level["@subsubheading"] = 4
+ Level["@subsubsection"] = 4
+ Level["@unnumberedsubsubsec"] = 4
+
+ # insure that we were called correctly
+ if (ARGC != 2) {
+ printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
+ exit 1
+ }
+
+ # init header counters
+ app_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ app_h = 0
+ l1_h = l2_h = l3_h = l4_h = 0
+}
+
+# skip lines we're not interested in
+/^[^@]/ || ! ($1 in Level) { next }
+
+Level[$1] == 1 {
+ if ($1 !~ /^@unnumbered/ || $1 !~ /heading/)
+ l1_h++
+ l2_h = l3_h = l4_h = 0
+ Ntabs = 0
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+Level[$1] == 2 {
+ l2_h++
+ l3_h = l4_h = 0
+ Ntabs = 1
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+Level[$1] == 3 {
+ l3_h++
+ l4_h = 0
+ Ntabs = 2
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+Level[$1] == 4 {
+ l4_h++
+ Ntabs = 3
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+# maketitle --- extract title
+
+function maketitle(str, text)
+{
+ $1 = "" # clobber section keyword
+ text = $0
+ gsub(/^[ \t]*/, "", text)
+ text = gensub(/@[a-z]+{/, "", "g", text)
+ text = gensub(/([^@])}/, "\\1", "g", text)
+ return text
+}
+
+# print_title --- print the title
+
+function print_title( i)
+{
+ for (i = 1; i <= Ntabs; i++)
+ printf "\t"
+ printf("%s %s\n", Number, Title)
+}
+
+# makenumber --- construct a heading number from levels and section command
+
+function makenumber(command, result, lev1)
+{
+ result = ""
+ if (command ~ /^@appendix/) {
+ if (Level[command] == 1)
+ app_h++
+
+ lev1 = substr(app_letters, app_h, 1)
+ } else if (command ~ /^@unnumbered/ || command ~ /heading/) {
+ lev1 = "(unnumbered)"
+ } else
+ lev1 = l1_h ""
+
+ result = lev1 "."
+ if (l2_h > 0) {
+ result = result l2_h "."
+ if (l3_h > 0) {
+ result = result l3_h "."
+ if (l4_h > 0) {
+ result = result l4_h "."
+ }
+ }
+ }
+ return result
+}
diff --git a/contrib/perldoc-all/GNUmakefile b/contrib/perldoc-all/GNUmakefile
new file mode 100644
index 0000000..319436e
--- /dev/null
+++ b/contrib/perldoc-all/GNUmakefile
@@ -0,0 +1,64 @@
+# $Id: GNUmakefile 5269 2013-06-29 16:11:15Z karl $
+# Sample Makefile to build Texinfo from the Perl POD documentation,
+# using pod2texi.
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+perl_pod_subdir = $(shell pwd)/perl-[0-9]*.*/pod
+texi_pod_doc = perldoc-all
+texi_pod_doc_incl = $(texi_pod_doc)-incl.texi
+texi_pod_subdir = $(texi_pod_doc)
+
+texinfo_srcdir = $(shell cd ../../ && pwd)
+pod2texi = perl $(texinfo_srcdir)/Pod-Simple-Texinfo/pod2texi.pl
+pod2texi_args = --base-level=section
+pod2texi_args += --preamble='' # we want our own
+pod2texi_args += --subdir=$(texi_pod_subdir)
+
+# Unfortunately have to use --no-validate since not all the names and
+# L<references> match up. Split HTML by chapter is the natural thing here.
+gendocs_args = --email bug-texinfo@gnu.org
+gendocs_args += --common "--no-warn --no-validate"
+gendocs_args += --split chapter
+gendocs_args += --no-ascii
+gendocs_args += --source $(texi_pod_subdir)
+gendocs_title = "Perl documentation in Texinfo"
+
+all: $(texi_pod_doc_incl)
+ rm -rf manual *.aux *.toc *.??
+# turns out the combined docs overflow one of TeX's arrays; increase it.
+ env save_size=100000 \
+ gendocs.sh $(gendocs_args) $(texi_pod_doc) $(gendocs_title)
+
+$(texi_pod_doc_incl): $(perl_pod_subdir)/*.pod
+ rm -rf $(texi_pod_subdir)
+# We remove all X<...> cross-reference constructs from the pods
+# before processing, since they are not parsed properly, resulting
+# in many chapters called simply "NAME", e.g., perldebug and perlsyn.
+# And we omit the numerous delta pods, which are uninteresting when
+# searching (and take tons of time and space to process).
+ cd $(perl_pod_subdir) \
+ && perl -p -i.bak -e 's,X<.*?>,,g' *.pod \
+ && $(pod2texi) -o $@ $(pod2texi_args) \
+ `ls *.pod | fgrep -v delta` \
+ && mv $(texi_pod_subdir) $@ ../..
+
+www_target = $(HOME)/gnu/www/www/software/perl/manual
+install:
+ cp -arf manual/. $(www_target)/.
+ ls -lt $(www_target)/html_chapter | tail # cvs rm -f obsolete files
+ # and cvs add new (status ?).
+
+# when running make dist, ensure we have none of the build files.
+# (Since the whole contrib/ directory is included in its entirety.)
+distclean:
+ rm -rf manual perl-5.*.* $(texi_pod_doc) $(texi_pod_doc_incl)
+ rm -rf *.?? *.??? *.info *~ \#*
diff --git a/contrib/perldoc-all/README b/contrib/perldoc-all/README
new file mode 100644
index 0000000..305c214
--- /dev/null
+++ b/contrib/perldoc-all/README
@@ -0,0 +1,19 @@
+$Id: README 5269 2013-06-29 16:11:15Z karl $
+texinfo/contrib/perldoc-all/README
+
+ Copyright 2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved.
+
+This stuff is about making Texinfo out of the standard Perl *.pod files.
+The results are at http://www.gnu.org/software/perl/manual.
+
+The idea is to unpack the perl distribution here, as in,
+ wget http://www.cpan.org/src/5.0/perl-5.NN.M.tar.gz # with right NN.M
+ tar xf perl-*.tar.gz
+and run (GNU) make. Aside from the result hopefully being useful in
+itself (just copy the .info file to an Info directory), it also serves
+as a nontrivial example of using pod2texi.
+
diff --git a/contrib/perldoc-all/gendocs_template b/contrib/perldoc-all/gendocs_template
new file mode 100644
index 0000000..d9726f6
--- /dev/null
+++ b/contrib/perldoc-all/gendocs_template
@@ -0,0 +1,76 @@
+<!--#include virtual="/server/header.html" -->
+<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title>
+<!--#include virtual="/server/banner.html" -->
+<h2>%%TITLE%%</h2>
+
+<address>GNU Project</address>
+<address>last updated %%DATE%%</address>
+
+<p>This translation of the <a href="http://perldoc.perl.org/">Perl
+documentation</a> from POD to Texinfo is not official, and not endorsed
+by the Perl developers (indeed, they haven't seen it). It was created
+by the GNU Texinfo developers because they found it useful to have the
+core Perl documentation available in Info and other formats, and thought
+they would share the results. Suggestions welcome.</p>
+
+<p>This output is created entirely by the Texinfo tools; see the <a
+href="http://cvs.savannah.gnu.org/viewvc/texinfo/contrib/perldoc-all/?root=texinfo">contrib/perldoc-all</a>
+directory in the Texinfo sources for the procedure used.</p>
+
+<p>This documentation (%%PACKAGE%%) is available in the following formats:</p>
+
+<ul>
+<li><a href="%%PACKAGE%%.html">HTML
+ (%%HTML_MONO_SIZE%%K bytes)</a> - entirely on one web page.</li>
+<li><a href="html_chapter/index.html">HTML</a> - with one web page per
+ chapter.</li>
+<li><a href="%%PACKAGE%%.html.gz">HTML compressed
+ (%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
+ one web page.</li>
+<li><a href="%%PACKAGE%%.html_chapter.tar.gz">HTML compressed
+ (%%HTML_CHAPTER_TGZ_SIZE%%K gzipped tar file)</a> -
+ with one web page per chapter.</li>
+<li><a href="%%PACKAGE%%.info.tar.gz">Info document
+ (%%INFO_TGZ_SIZE%%K bytes gzipped tar file)</a>.</li>
+<li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file
+ (%%DVI_GZ_SIZE%%K bytes gzipped)</a>.</li>
+<li><a href="%%PACKAGE%%.pdf">PDF file
+ (%%PDF_SIZE%%K bytes)</a>.</li>
+<li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source
+ (%%TEXI_TGZ_SIZE%%K bytes gzipped tar file).</a></li>
+</ul>
+
+<p>You can <a href="http://shop.fsf.org/">buy printed copies of
+some manuals</a> (among other items) from the Free Software Foundation;
+this helps support FSF activities.</p>
+
+<p>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%%
+script</a>.)</p>
+
+<!-- If needed, change the copyright block at the bottom. In general,
+ all pages on the GNU web server should have the section about
+ verbatim copying. Please do NOT remove this without talking
+ with the webmasters first.
+ Please make sure the copyright date is consistent with the document
+ and that it is like this: "2001, 2002", not this: "2001-2002". -->
+</div><!-- for id="content", starts in the include above -->
+<!--#include virtual="/server/footer.html" -->
+<div id="footer">
+
+<p>Please send general FSF &amp; GNU inquiries to
+<a href="mailto:gnu@gnu.org">&lt;gnu@gnu.org&gt;</a>.
+There are also <a href="/contact/">other ways to contact</a>
+the FSF.<br />
+Please send broken links and other corrections or suggestions to
+<a href="mailto:%%EMAIL%%">&lt;%%EMAIL%%&gt;</a>.</p>
+
+<p>Copyright &copy; 2013 Free Software Foundation, Inc.</p>
+
+<p>This page is licensed under a <a rel="license"
+href="http://creativecommons.org/licenses/by-nd/3.0/us/">Creative
+Commons Attribution-NoDerivs 3.0 United States License</a>.</p>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/contrib/perldoc-all/perldoc-all.texi b/contrib/perldoc-all/perldoc-all.texi
new file mode 100644
index 0000000..6b38bd5
--- /dev/null
+++ b/contrib/perldoc-all/perldoc-all.texi
@@ -0,0 +1,34 @@
+\input texinfo
+@c This top-level file is so trivial, it has to be public domain.
+@setfilename perldoc-all.info
+@settitle Perl pod documentation
+@finalout
+@tex
+\global\hfuzz=\maxdimen
+\global\hbadness=10000
+@end tex
+
+@shortcontents
+@contents
+
+@ifnottex
+@node Top
+@top Perl pod documentation
+
+This translation of the Perl documentation
+(@url{http://perldoc.perl.org}) from POD to Texinfo is not official,
+and not endorsed by the Perl developers (indeed, they haven't seen
+it). It was created by the GNU Texinfo developers because they found
+it useful to have the Perl documentation available in Info and other
+formats, and thought they would share the results. Suggestions welcome.
+
+This is created entirely by the Texinfo tools; see the
+@url{http://svn.savannah.gnu.org/viewvc/trunk/contrib/perldoc-all/?root=texinfo,
+@file{contrib/perldoc-all}} directory in the Texinfo sources for the
+procedure used. The output is available at
+@url{http://www.gnu.org/software/perl/manual}.
+@end ifnottex
+
+@include perldoc-all-incl.texi
+
+@bye
diff --git a/contrib/prepinfo.awk b/contrib/prepinfo.awk
new file mode 100644
index 0000000..18e668b
--- /dev/null
+++ b/contrib/prepinfo.awk
@@ -0,0 +1,355 @@
+#! /usr/local/bin/gawk -f
+
+# prepinfo.awk --- fix node lines and menus
+#
+# Copyright 1998 Arnold Robbins, arnold@gnu.org
+#
+# PREPINFO 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 3 of the License, or
+# (at your option) any later version.
+#
+# PREPINFO is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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, see <http://www.gnu.org/licenses/>.
+
+BEGIN \
+{
+ # manifest constants
+ TRUE = 1
+ FALSE = 0
+
+ # Levels at which different nodes can be
+ Level["@top"] = 0
+ Level["@appendix"] = 1
+ Level["@chapter"] = 1
+ Level["@majorheading"] = 1
+ Level["@unnumbered"] = 1
+ Level["@appendixsec"] = 2
+ Level["@heading"] = 2
+ Level["@section"] = 2
+ Level["@unnumberedsec"] = 2
+ Level["@unnumberedsubsec"] = 3
+ Level["@appendixsubsec"] = 3
+ Level["@subheading"] = 3
+ Level["@subsection"] = 3
+ Level["@appendixsubsubsec"] = 4
+ Level["@subsubheading"] = 4
+ Level["@subsubsection"] = 4
+ Level["@unnumberedsubsubsec"] = 4
+
+ # Length of menus
+ Menumargin = 78
+
+ # Length of menu item
+ Min_menitem_length = 29
+
+ # insure that we were called correctly
+ if (ARGC != 2) {
+ printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
+ exit 1
+ }
+
+ # Arrange for two passes over input file
+ Pass = 1
+ ARGV[2] = "Pass=2"
+ ARGV[3] = ARGV[1]
+ ARGC = 4
+ Lastlevel = -1
+
+ # Initialize stacks
+ Up[-1] = "(dir)"
+ Prev[0] = "(dir)"
+
+ if (Debug == "args") {
+ for (i = 0; i < ARGC; i++)
+ printf("ARGV[%d] = %s\n", i, ARGV[i]) > "/dev/stderr"
+ }
+}
+
+$1 == "@node" \
+{
+ Name = getnodename($0)
+ Nodeseen = TRUE
+
+ if ((l = length(Name)) > Maxlen)
+ Maxlen = l
+
+ if (Debug == "nodenames")
+ printf("Name = %s\n", Name) > "/dev/stderr"
+
+ if (Pass == 1)
+ next
+}
+
+Pass == 1 && /^@c(omment)?[ \t]+fakenode/ \
+{
+ if (Debug == "fakenodes")
+ printf("fakenode at %d\n", FNR) > "/dev/stderr"
+ Fakenode = TRUE
+ next
+}
+
+Pass == 1 && ($1 in Level) \
+{
+ # skip fake nodes --- titles without associated @node lines
+ if (Fakenode) {
+ if (Debug == "fakenodes")
+ printf("%s at %d is a fakenode\n", $1, FNR) > "/dev/stderr"
+ Fakenode = FALSE
+ next
+ }
+
+ if (Debug == "titles")
+ printf("Processing %s: Name = %s\n", $1, Name) > "/dev/stderr"
+
+ # save type
+ type = $1
+
+ if (! Nodeseen) {
+ err_prefix()
+ printf("%s line with no @node or fakenode line\n",
+ type) > "/dev/stderr"
+ Badheading[FNR] = 1
+ # ??? used ???
+ next
+ } else
+ Nodeseen = FALSE # reset it
+
+ # Squirrel away the info
+ levelnum = Level[type]
+ Node[Name ".level"] = levelnum
+ Node[Name ".name"] = Name
+ if (Debug == "titles") {
+ printf("Node[%s\".level\"] = %s\n", Name, Node[Name ".level"]) > "/dev/stderr"
+ printf("Node[%s\".name\"] = %s\n", Name, Node[Name ".name"]) > "/dev/stderr"
+ }
+
+ if (levelnum == Lastlevel) { # e.g., two sections in a row
+ Node[Name ".up"] = Up[levelnum - 1]
+ if (levelnum in Prev) {
+ Node[Prev[levelnum] ".next"] = Name
+ Node[Name ".prev"] = Prev[levelnum]
+ }
+ Prev[levelnum] = Name
+ Up[levelnum] = Name # ???
+ } else if (levelnum < Lastlevel) { # section, now chapter
+ Lastlevel = levelnum
+ Node[Name ".up"] = Up[levelnum - 1]
+ if (levelnum in Prev) {
+ Node[Name ".prev"] = Prev[levelnum]
+ Node[Prev[levelnum] ".next"] = Name
+ }
+ Prev[levelnum] = Name
+ Up[levelnum] = Name
+ } else { # chapter, now section, levelnum > Lastlevel
+ Node[Name ".up"] = Up[levelnum - 1]
+ Node[Up[Lastlevel] ".child"] = Name
+ Up[levelnum] = Name
+ Prev[levelnum] = Name
+ Lastlevel = levelnum
+ }
+
+ # For master menu
+ if (Level[$1] >= 2)
+ List[++Sequence] = Name
+
+ if (Debug == "titles") {
+ printf("Node[%s\".prev\"] = %s\n", Name, Node[Name ".prev"]) > "/dev/stderr"
+ printf("Node[%s\".up\"] = %s\n", Name, Node[Name ".up"]) > "/dev/stderr"
+ printf("Node[%s\".child\"] = %s\n", Name, Node[Name ".child"]) > "/dev/stderr"
+ }
+}
+
+Pass == 2 && Debug == "dumptitles" && FNR <= 1 \
+{
+ for (i in Node)
+ printf("Node[%s] = %s\n", i, Node[i]) | "sort 1>&2"
+ close("sort 1>&2")
+}
+
+/^@menu/ && Pass == 1, /^@end[ \t]+menu/ && Pass == 1 \
+{
+ if (/^@menu/ || /^@end[ \t]+menu/)
+ next
+
+# if (Debug == "menu")
+# printf("processing: %s\n", $0) > "/dev/stderr"
+
+ if (/^\*/) {
+ if (In_menitem) { # file away info from previousline
+ Node[node ".mendesc"] = desc
+ Node[node ".longdesc"] = longdesc
+ if (Debug == "mendesc") {
+ printf("Node[%s.mendesc] = %s\n",
+ node, Node[node ".mendesc"]) > "/dev/stderr"
+ printf("Node[%s.longdesc] = %s\n",
+ node, Node[node ".longdesc"]) > "/dev/stderr"
+ }
+ }
+ In_menitem = TRUE
+
+ # pull apart menu item
+ $1 = "" # nuke ``*''
+ $0 = $0 # reparse line
+ i1 = index($0, ":")
+ if (i1 <= 0) {
+ err_prefix()
+ printf("badly formed menu item") > "/dev/stderr"
+ next
+ }
+ if (substr($0, i1+1, 1) != ":") { # desc: node. long desc
+ i2 = index($0, ".")
+ if (i2 <= 0) {
+ err_prefix()
+ printf("badly formed menu item") > "/dev/stderr"
+ next
+ }
+ desc = substr($0, 1, i1 - 1)
+ sub(/^[ \t]+/, "", node)
+ sub(/[ \t]+$/, "", node)
+ longdesc = substr($0, i2 + 1)
+ } else { # nodname:: long desc
+ desc = ""
+ node = substr($0, 1, i1 - 1)
+ sub(/^[ \t]+/, "", node)
+ sub(/[ \t]+$/, "", node)
+ longdesc = substr($0, i1 + 2)
+ }
+ } else if (In_menitem) { # continuation line
+ longdesc = longdesc " " $0
+ } else
+ In_menitem = FALSE
+
+ Node[node ".mendesc"] = desc
+ Node[node ".longdesc"] = longdesc
+ if (Debug == "mendesc") {
+ printf("Node[%s.mendesc] = %s\n",
+ node, Node[node ".mendesc"]) > "/dev/stderr"
+ printf("Node[%s.longdesc] = %s\n",
+ node, Node[node ".longdesc"]) > "/dev/stderr"
+ }
+
+ if (Debug == "menu")
+ printf("Menu:: Name %s: desc %s: longdesc %s\n",
+ node, desc, longdesc) > "/dev/stderr"
+}
+
+function err_prefix()
+{
+ printf("%s: %s: %d: ", ARGV[0], FILENAME, FNR) > "/dev/stderr"
+}
+
+function getnodename(str)
+{
+ sub(/@node[ \t]+/, "", str)
+ sub(/,.*/, "", str)
+ if (Debug == "nodenames")
+ printf("getnodename: return %s\n", str) > "/dev/stderr"
+ return str
+}
+
+Pass == 2 && /^@node/ \
+{
+ Name = getnodename($0)
+
+ # Top node is special. It's next is the first child
+ n = Node[Name ".next"]
+ if (Node[Name ".level"] == 0 && n == "")
+ n = Node[Name ".child"]
+
+ printf("@node %s, %s, %s, %s\n", Name, n,
+ Node[Name ".prev"] ? Node[Name ".prev"] : Node[Name ".up"],
+ Node[Name ".up"])
+ next
+}
+
+Pass == 2 && /^@menu/ \
+{
+ # First, nuke current contents of menu
+ do {
+ if ((getline) <= 0) {
+ err_prefix()
+ printf("unexpected EOF inside menu\n") > "/dev/stderr"
+ exit 1
+ }
+ } while (! /^@end[ \t]+menu/)
+
+ # next, compute maximum length of a node name
+ max = 0
+ for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
+ if ((n ".desc") in Node)
+ s = Node[n ".desc"] ": " n "."
+ else
+ s = n "::"
+ l = length(s)
+ if (l > max)
+ max = l
+ }
+ if (max < Min_menitem_length)
+ max = Min_menitem_length
+
+ # now dump the menu
+ print "@menu"
+
+ for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
+ print_menuitem(n, max)
+ }
+ print_menuitem(n, max)
+
+ if (Name == "Top") { # Master Menu
+ if (Maxlen < Min_menitem_length)
+ Maxlen = Min_menitem_length
+ print ""
+ for (i = 1; i <= Sequence; i++)
+ print_menuitem(List[i], Maxlen)
+ print ""
+ }
+ print "@end menu"
+ next
+}
+
+Pass == 2 # print
+
+
+function print_menuitem(n, max, nodesc, i, dwords, count, p)
+{
+ nodesc = FALSE
+ if (! ((n ".longdesc") in Node)) {
+ err_prefix()
+ printf("warning: %s: no long description\n", n) > "/dev/stderr"
+ nodesc = TRUE
+ } else {
+ for (i in dwords)
+ delete dwords[i]
+ count = split(Node[n ".longdesc"], dwords, "[ \t\n]+")
+ }
+ if ((n ".desc") in Node)
+ s = Node[n ".desc"] ": " n "."
+ else
+ s = n "::"
+ printf("* %-*s", max, s)
+
+ if (Debug == "mendescitem")
+ printf("<* %-*s>\n", max, s) > "/dev/stderr"
+
+ p = max + 2
+ if (! nodesc) {
+ for (i = 1; i <= count; i++) {
+ l = length(dwords[i])
+ if (l == 0)
+ continue
+ if (p + l + 1 > Menumargin) {
+ printf("\n%*s", max + 2, " ")
+ p = max + 2
+ }
+ printf(" %s", dwords[i])
+ p += l + 1
+ }
+ }
+ print ""
+}
diff --git a/contrib/tex3patch b/contrib/tex3patch
new file mode 100755
index 0000000..046c794
--- /dev/null
+++ b/contrib/tex3patch
@@ -0,0 +1,70 @@
+#!/bin/sh
+# Auxiliary script to work around TeX 3.0 bug. ---- tex3patch ----
+# patches texinfo.tex in current directory, or in directory given as arg.
+
+ANYVERSION=no
+
+for arg in $1 $2
+do
+ case $arg in
+ --dammit | -d ) ANYVERSION=yes ;;
+
+ * ) dir=$arg
+ esac
+done
+
+if [ -z "$dir" ]; then
+ dir='.'
+fi
+
+if [ 2 -lt $# ] || [ ! -f "$dir/texinfo.tex" ]; then
+ echo "To patch texinfo.tex for peaceful coexistence with Unix TeX 3.0,"
+ echo "run $0"
+ echo "with no arguments in the same directory as texinfo.tex; or run"
+ echo " $0 DIRECTORY"
+ echo "(where DIRECTORY is a path leading to texinfo.tex)."
+ exit
+fi
+
+if [ -z "$TMPDIR" ]; then
+ TMPDIR=/tmp
+fi
+
+echo "Checking for \`dummy.tfm'"
+
+( cd $TMPDIR; tex '\relax \batchmode \font\foo=dummy \bye' )
+
+grep -s '3.0' $TMPDIR/texput.log
+if [ 1 = "$?" ] && [ "$ANYVERSION" != "yes" ]; then
+ echo "You probably do not need this patch,"
+ echo "since your TeX does not seem to be version 3.0."
+ echo "If you insist on applying the patch, run $0"
+ echo "again with the option \`--dammit'"
+ exit
+fi
+
+grep -s 'file not found' $TMPDIR/texput.log
+if [ 0 = $? ]; then
+ echo "This patch requires the dummy font metric file \`dummy.tfm',"
+ echo "which does not seem to be part of your TeX installation."
+ echo "Please get your TeX maintainer to install \`dummy.tfm',"
+ echo "then run this script again."
+ exit
+fi
+rm $TMPDIR/texput.log
+
+echo "Patching $dir/texinfo.tex"
+
+sed -e 's/%%*\\font\\nullfont/\\font\\nullfont/' \
+ $dir/texinfo.tex >$TMPDIR/texinfo.tex
+mv $dir/texinfo.tex $dir/texinfo.tex-distrib; mv $TMPDIR/texinfo.tex $dir
+
+if [ 0 = $? ]; then
+ echo "Patched $dir/texinfo.tex to avoid TeX 3.0 bug."
+ echo "The original version is saved as $dir/texinfo.tex-distrib."
+else
+ echo "Patch failed. Sorry."
+fi
+----------------------------------------tex3patch ends
+
+
diff --git a/contrib/texi-docstring-magic.el b/contrib/texi-docstring-magic.el
new file mode 100644
index 0000000..0de817d
--- /dev/null
+++ b/contrib/texi-docstring-magic.el
@@ -0,0 +1,345 @@
+;; texi-docstring-magic.el -- munge internal docstrings into texi
+;;
+;; Keywords: lisp, docs, tex
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Copyright (C) 1998 David Aspinall
+;; Maintainer: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; This package is distributed under the terms of the
+;; GNU General Public License, Version 3.
+;; You should have a copy of the GPL with your version of
+;; GNU Emacs or the Texinfo distribution.
+;;
+;;
+;; This package generates Texinfo source fragments from Emacs
+;; docstrings. This avoids documenting functions and variables
+;; in more than one place, and automatically adds Texinfo markup
+;; to docstrings.
+;;
+;; It relies heavily on you following the Elisp documentation
+;; conventions to produce sensible output, check the Elisp manual
+;; for details. In brief:
+;;
+;; * The first line of a docstring should be a complete sentence.
+;; * Arguments to functions should be written in upper case: ARG1..ARGN
+;; * User options (variables users may want to set) should have docstrings
+;; beginning with an asterisk.
+;;
+;; Usage:
+;;
+;; Write comments of the form:
+;;
+;; @c TEXI DOCSTRING MAGIC: my-package-function-or-variable-name
+;;
+;; In your texi source, mypackage.texi. From within an Emacs session
+;; where my-package is loaded, visit mypackage.texi and run
+;; M-x texi-docstring-magic to update all of the documentation strings.
+;;
+;; This will insert @defopt, @deffn and the like underneath the
+;; magic comment strings.
+;;
+;; The default value for user options will be printed.
+;;
+;; Symbols are recognized if they are defined for faces, functions,
+;; or variables (in that order).
+;;
+;; Automatic markup rules:
+;;
+;; 1. Indented lines are gathered into @lisp environment.
+;; 2. Pieces of text `stuff' or surrounded in quotes marked up with @samp.
+;; 3. Words *emphasized* are made @strong{emphasized}
+;; 4. Words sym-bol which are symbols become @code{sym-bol}.
+;; 5. Upper cased words ARG corresponding to arguments become @var{arg}.
+;; In fact, you can any word longer than three letters, so that
+;; metavariables can be used easily.
+;; FIXME: to escape this, use `ARG'
+;; 6. Words 'sym which are lisp-quoted are marked with @code{'sym}.
+;;
+;; -----
+;;
+;; Useful key binding when writing Texinfo:
+;;
+;; (define-key TeXinfo-mode-map "C-cC-d" 'texi-docstring-magic-insert-magic)
+;;
+;; -----
+;;
+;; Useful enhancements to do:
+;;
+;; * Use customize properties (e.g. group, simple types)
+;; * Look for a "texi-docstring" property for symbols
+;; so TeXInfo can be defined directly in case automatic markup
+;; goes badly wrong.
+;; * Add tags to special comments so that user can specify face,
+;; function, or variable binding for a symbol in case more than
+;; one binding exists.
+;;
+;; ------
+
+(defun texi-docstring-magic-splice-sep (strings sep)
+ "Return concatenation of STRINGS spliced together with separator SEP."
+ (let (str)
+ (while strings
+ (setq str (concat str (car strings)))
+ (if (cdr strings)
+ (setq str (concat str sep)))
+ (setq strings (cdr strings)))
+ str))
+
+(defconst texi-docstring-magic-munge-table
+ '(;; 1. Indented lines are gathered into @lisp environment.
+ ("\\(^.*\\S-.*$\\)"
+ t
+ (let
+ ((line (match-string 0 docstring)))
+ (if (eq (char-syntax (string-to-char line)) ?\ )
+ ;; whitespace
+ (if in-quoted-region
+ line
+ (setq in-quoted-region t)
+ (concat "@lisp\n" line))
+ ;; non-white space
+ (if in-quoted-region
+ (progn
+ (setq in-quoted-region nil)
+ (concat "@end lisp\n" line))
+ line))))
+ ;; 2. Pieces of text `stuff' or surrounded in quotes
+ ;; are marked up with @samp. NB: Must be backquote
+ ;; followed by forward quote for this to work.
+ ;; Can't use two forward quotes else problems with
+ ;; symbols.
+ ;; Odd hack: because ' is a word constituent in text/texinfo
+ ;; mode, putting this first enables the recognition of args
+ ;; and symbols put inside quotes.
+ ("\\(`\\([^']+\\)'\\)"
+ t
+ (concat "@samp{" (match-string 2 docstring) "}"))
+ ;; 3. Words *emphasized* are made @strong{emphasized}
+ ("\\(\\*\\(\\w+\\)\\*\\)"
+ t
+ (concat "@strong{" (match-string 2 docstring) "}"))
+ ;; 4. Words sym-bol which are symbols become @code{sym-bol}.
+ ;; Must have at least one hyphen to be recognized,
+ ;; terminated in whitespace, end of line, or punctuation.
+ ;; (Only consider symbols made from word constituents
+ ;; and hyphen.
+ ("\\(\\(\\w+\\-\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
+ (or (boundp (intern (match-string 2 docstring)))
+ (fboundp (intern (match-string 2 docstring))))
+ (concat "@code{" (match-string 2 docstring) "}"
+ (match-string 4 docstring)))
+ ;; 5. Upper cased words ARG corresponding to arguments become
+ ;; @var{arg}
+ ;; In fact, include any word so long as it is more than 3 characters
+ ;; long. (Comes after symbols to avoid recognizing the
+ ;; lowercased form of an argument as a symbol)
+ ;; FIXME: maybe we don't want to downcase stuff already
+ ;; inside @samp
+ ;; FIXME: should - terminate? should _ be included?
+ ("\\([A-Z0-9\\-]+\\)\\(/\\|\)\\|}\\|\\s-\\|\\s.\\|$\\)"
+ (or (> (length (match-string 1 docstring)) 3)
+ (member (downcase (match-string 1 docstring)) args))
+ (concat "@var{" (downcase (match-string 1 docstring)) "}"
+ (match-string 2 docstring)))
+
+ ;; 6. Words 'sym which are lisp quoted are
+ ;; marked with @code.
+ ("\\(\\(\\s-\\|^\\)'\\(\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
+ t
+ (concat (match-string 2 docstring)
+ "@code{'" (match-string 3 docstring) "}"
+ (match-string 5 docstring)))
+ ;; 7,8. Clean up for @lisp environments left with spurious newlines
+ ;; after 1.
+ ("\\(\\(^\\s-*$\\)\n@lisp\\)" t "@lisp")
+ ("\\(\\(^\\s-*$\\)\n@end lisp\\)" t "@end lisp"))
+ "Table of regexp matches and replacements used to markup docstrings.
+Format of table is a list of elements of the form
+ (regexp predicate replacement-form)
+If regexp matches and predicate holds, then replacement-form is
+evaluated to get the replacement for the match.
+predicate and replacement-form can use variables arg,
+and forms such as (match-string 1 docstring)
+Match string 1 is assumed to determine the
+length of the matched item, hence where parsing restarts from.
+The replacement must cover the whole match (match string 0),
+including any whitespace included to delimit matches.")
+
+
+(defun texi-docstring-magic-munge-docstring (docstring args)
+ "Markup DOCSTRING for texi according to regexp matches."
+ (let ((case-fold-search nil))
+ (dolist (test texi-docstring-magic-munge-table docstring)
+ (let ((regexp (nth 0 test))
+ (predicate (nth 1 test))
+ (replace (nth 2 test))
+ (i 0)
+ in-quoted-region)
+
+ (while (and
+ (< i (length docstring))
+ (string-match regexp docstring i))
+ (setq i (match-end 1))
+ (if (eval predicate)
+ (let* ((origlength (- (match-end 0) (match-beginning 0)))
+ (replacement (eval replace))
+ (newlength (length replacement)))
+ (setq docstring
+ (replace-match replacement t t docstring))
+ (setq i (+ i (- newlength origlength))))))
+ (if in-quoted-region
+ (setq docstring (concat docstring "\n@end lisp"))))))
+ ;; Force a new line after (what should be) the first sentence,
+ ;; if not already a new paragraph.
+ (let*
+ ((pos (string-match "\n" docstring))
+ (needscr (and pos
+ (not (string= "\n"
+ (substring docstring
+ (1+ pos)
+ (+ pos 2)))))))
+ (if (and pos needscr)
+ (concat (substring docstring 0 pos)
+ "@*\n"
+ (substring docstring (1+ pos)))
+ docstring)))
+
+(defun texi-docstring-magic-texi (env grp name docstring args &optional endtext)
+ "Make a texi def environment ENV for entity NAME with DOCSTRING."
+ (concat "@def" env (if grp (concat " " grp) "") " " name
+ " "
+ (texi-docstring-magic-splice-sep args " ")
+ ;; " "
+ ;; (texi-docstring-magic-splice-sep extras " ")
+ "\n"
+ (texi-docstring-magic-munge-docstring docstring args)
+ "\n"
+ (or endtext "")
+ "@end def" env "\n"))
+
+(defun texi-docstring-magic-format-default (default)
+ "Make a default value string for the value DEFAULT.
+Markup as @code{stuff} or @lisp stuff @end lisp."
+ (let ((text (format "%S" default)))
+ (concat
+ "\nThe default value is "
+ (if (string-match "\n" text)
+ ;; Carriage return will break @code, use @lisp
+ (if (stringp default)
+ (concat "the string: \n@lisp\n" default "\n@end lisp\n")
+ (concat "the value: \n@lisp\n" text "\n@end lisp\n"))
+ (concat "@code{" text "}.\n")))))
+
+
+(defun texi-docstring-magic-texi-for (symbol)
+ (cond
+ ;; Faces
+ ((find-face symbol)
+ (let*
+ ((face symbol)
+ (name (symbol-name face))
+ (docstring (or (face-doc-string face)
+ "Not documented."))
+ (useropt (eq ?* (string-to-char docstring))))
+ ;; Chop off user option setting
+ (if useropt
+ (setq docstring (substring docstring 1)))
+ (texi-docstring-magic-texi "fn" "Face" name docstring nil)))
+ ((fboundp symbol)
+ ;; Functions.
+ ;; We don't handle macros, aliases, or compiled fns properly.
+ (let*
+ ((function symbol)
+ (name (symbol-name function))
+ (docstring (or (documentation function)
+ "Not documented."))
+ (def (symbol-function function))
+ (argsyms (cond ((eq (car-safe def) 'lambda)
+ (nth 1 def))))
+ (args (mapcar 'symbol-name argsyms)))
+ (if (commandp function)
+ (texi-docstring-magic-texi "fn" "Command" name docstring args)
+ (texi-docstring-magic-texi "un" nil name docstring args))))
+ ((boundp symbol)
+ ;; Variables.
+ (let*
+ ((variable symbol)
+ (name (symbol-name variable))
+ (docstring (or (documentation-property variable
+ 'variable-documentation)
+ "Not documented."))
+ (useropt (eq ?* (string-to-char docstring)))
+ (default (if useropt
+ (texi-docstring-magic-format-default
+ (default-value symbol)))))
+ ;; Chop off user option setting
+ (if useropt
+ (setq docstring (substring docstring 1)))
+ (texi-docstring-magic-texi
+ (if useropt "opt" "var") nil name docstring nil default)))
+ (t
+ (error "Don't know anything about symbol %s" (symbol-name symbol)))))
+
+(defconst texi-docstring-magic-comment
+ "@c TEXI DOCSTRING MAGIC:"
+ "Magic string in a texi buffer expanded into @defopt, or @deffn.")
+
+(defun texi-docstring-magic ()
+ "Update all texi docstring magic annotations in buffer."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((magic (concat "^"
+ (regexp-quote texi-docstring-magic-comment)
+ "\\s-*\\(\\(\\w\\|\\-\\)+\\)$"))
+ p
+ symbol)
+ (while (re-search-forward magic nil t)
+ (setq symbol (intern (match-string 1)))
+ (forward-line)
+ (setq p (point))
+ ;; If comment already followed by an environment, delete it.
+ (if (and
+ (looking-at "@def\\(\\w+\\)\\s-")
+ (search-forward (concat "@end def" (match-string 1)) nil t))
+ (progn
+ (forward-line)
+ (delete-region p (point))))
+ (insert
+ (texi-docstring-magic-texi-for symbol))))))
+
+(defun texi-docstring-magic-face-at-point ()
+ (ignore-errors
+ (let ((stab (syntax-table)))
+ (unwind-protect
+ (save-excursion
+ (set-syntax-table emacs-lisp-mode-syntax-table)
+ (or (not (zerop (skip-syntax-backward "_w")))
+ (eq (char-syntax (char-after (point))) ?w)
+ (eq (char-syntax (char-after (point))) ?_)
+ (forward-sexp -1))
+ (skip-chars-forward "'")
+ (let ((obj (read (current-buffer))))
+ (and (symbolp obj) (find-face obj) obj)))
+ (set-syntax-table stab)))))
+
+(defun texi-docstring-magic-insert-magic (symbol)
+ (interactive
+ (let* ((v (or (variable-at-point)
+ (function-at-point)
+ (texi-docstring-magic-face-at-point)))
+ (val (let ((enable-recursive-minibuffers t))
+ (completing-read
+ (if v
+ (format "Magic docstring for symbol (default %s): " v)
+ "Magic docstring for symbol: ")
+ obarray '(lambda (sym)
+ (or (boundp sym)
+ (fboundp sym)
+ (find-face sym)))
+ t nil 'variable-history))))
+ (list (if (equal val "") v (intern val)))))
+ (insert "\n" texi-docstring-magic-comment " " (symbol-name symbol)))
+
+
+(provide 'texi-docstring-magic)
diff --git a/contrib/texifont/README b/contrib/texifont/README
new file mode 100644
index 0000000..8fdb955
--- /dev/null
+++ b/contrib/texifont/README
@@ -0,0 +1,31 @@
+$Id: README 5191 2013-02-23 00:11:18Z karl $
+texinfo/contrib/texifont/README
+
+Everything in this directory is public domain.
+
+The main source file is fsel.tex, tested by ftest.tex, documentation
+(such as it is) in texifont.txi.
+
+The story here is that Oleg Katsitadze and I (Karl Berry) collaborated
+in the mid-2000s on a new font system for Texinfo (and that could work
+with Eplain). Oleg wrote essentially all the code, while I advised on
+the design, etc.
+
+The idea was to support all the widely-available free font families and
+widely used input encodings. getting away from of the current
+hardwiring of Computer Modern in texinfo.tex. The example at the end of
+documentation gives the basic flavor. As it stands, it is not hooked
+into texinfo.tex or Texinfo documents at all. That is not the hard part :).
+
+Unfortunately, it never came to fruition. Even more unfortunately, Oleg
+and I can't even give any real specifics of what the "next thing" to do
+is, we've lost the details in the haze of time. As I recall, the
+current problem was something about caching of glyphs to avoid
+unnecessary (and greatly excessive) switching of fonts. In addition,
+"attributes" (fattr.tex) were starting to come into play. But it all
+remains a work in progress.
+
+Anyway, I'm not sanguine about anyone ever doing anything with this, but
+just in case some super-duper TeX hacker has too much time on their
+hands :) and wants to pick it up, here it is. Contact
+bug-texinfo@gnu.org ...
diff --git a/contrib/texifont/enctest.tex b/contrib/texifont/enctest.tex
new file mode 100644
index 0000000..eef8c6b
--- /dev/null
+++ b/contrib/texifont/enctest.tex
@@ -0,0 +1,45 @@
+\catcode`\@=11
+\input ienc
+\input oenc
+\input fsel
+\catcode`\@=12
+
+\def\changedocenc#1 {%
+ \message{^^J** #1}%
+ \documentencoding #1
+}
+
+\hfuzz=\maxdimen
+%\tracingfonts2
+
+\setfontencoding{T1}\setfontfamily{LMRoman}\selectfont
+\changedocenc ISO-8859-1
+\input sample.latin1 % Icelandic
+
+\bigskip
+\changedocenc ISO-8859-15
+\input sample.latin9 % French
+
+\bigskip
+\changedocenc ISO-8859-2
+\input sample.latin2 % Czech
+
+\bigskip
+\changedocenc ISO-8859-2
+\setfontencoding{OT1}\setfontfamily{CMRoman}\selectfont
+\input sample.latin2 % Czech
+
+\bigskip
+\setfontencoding{T2A}\setfontfamily{LHRoman}\selectfont
+\changedocenc KOI8-R
+\input sample.koi8r % Russian
+
+\bigskip
+\changedocenc CP1251
+\input sample.cp1251 % Russian
+
+\bye
+
+% Local variables:
+% compile-command: "tex --interact=nonstopmode enctest.tex"
+% End:
diff --git a/contrib/texifont/fattr.tex b/contrib/texifont/fattr.tex
new file mode 100644
index 0000000..0843cf4
--- /dev/null
+++ b/contrib/texifont/fattr.tex
@@ -0,0 +1,803 @@
+% font set Computer Modern, Latin Modern, Bera
+% font family CMRoman, CMTypewriter, CMSansSerif
+%
+% font feature slant, weight, width
+% font attribute sl, it, bold, cond
+%
+% fontfile
+%
+% Font features and attributes:
+%
+% size design point size
+% encoding ot1, oml, oms, omx, t1, ts1, t2a
+% slant up, sl, it, ui, cursive
+% weight lt, med, semib, bold, bx,
+% width cond, normal, ext
+% figures oldfigures, liningfigures
+% caps normalcaps, allcaps, smallcaps, nocaps
+
+\catcode`@=11
+%
+% \fsz:CMRoman/<OT1>/<up>/<med>/<normal>/<liningfigures>/<normalcaps>
+% ->
+% cmr5/5,cmr7/7,cmr8/8,cmr9/9,cmr10/10,cmr12/12,cmr17/17,.
+%
+% {CMRoman}{b}{bx}
+% {OML,CMRoman}{m}{up}
+% {OML,CMRoman}{bx}{up}
+% {OML,CMRoman}{b}{bx}
+% {CMSans}{it}{sl}
+% {CMSans}{b}{bx}
+% {CMSans,OML}{}{CMRoman}
+% {ConcreteRoman}{b}{LMSans,b}
+% {OT1,CMMath}{}{CMRoman,n}
+% {OMX,CMMath}{bx}{m}
+%
+
+\input eplain
+
+%
+%
+%
+% Font-related logging. Meanings of \ftracelevel values are:
+%
+% 0 - none
+% 1 - warning
+% 2 - debug
+% 3 - verbose
+\newcount\ftracelevel
+\ftracelevel=1
+%
+\def\f@warning{\f@trace0}%
+\def\f@debug {\f@trace1}%
+\def\f@verbose{\f@trace2}%
+\def\f@trace#1{%
+ \ifnum#1<\ftracelevel
+ \expandafter\message
+ \else
+ \expandafter\gobble
+ \fi
+}%
+%
+%
+%
+% Defining new fonts.
+%
+% \newfont MAG-FACTOR FILE-NAME DESIGN-SIZE [ATTRIBUTES]
+%
+% If ATTRIBUTES is not given, will reuse ATTRIBUTES from the
+% last \newfont call with ATTRIBUTES given. To define a font with
+% empty attributes, pass \empty or {} for ATTRIBUTES.
+\let\newfont@last@attributes\empty
+%
+{\catcode`\^^M=12 % Comment out all line ends from now on.
+\gdef\newfont{\begingroup \catcode`\^^M=12 \@newfont}%
+\gdef\@newfont#1 #2 #3^^M{\endgroup%
+ \def\newfont@mag{#1}%
+ \def\newfont@fname{#2}%
+ \@new@font#3 ^^M%
+}%
+\gdef\@new@font #1 #2^^M{% DESIGN-SIZE [ATTRIBUTES]
+ \get@dimen{#1}% Convert font size into a dimen.
+ \if^^M#2^^M% Assume #2 contains no (leading) ^^Ms.
+ % #2 is empty, continue to use the current \newfont@last@attributes.
+ \else%
+ \@new@font@#2^^M% Redefine \newfont@last@attributes, removing the space.
+ \fi%
+ \def@newfont%
+}%
+\gdef\@new@font@#1 ^^M{\def\newfont@last@attributes{#1}}%
+}%
+%
+%\def\def@newfont{%
+% \message{^^J.\newfont@mag.\newfont@fname.\the\dimen@.\newfont@last@attributes.}%
+%}%
+%
+\def\def@newfont{%
+ % Empty \ff@temp0, \ff@temp1, ..., \ff@temp<MAX-ITEM-IDX>.
+ \ff@temp@reset
+ \for\ff@temp@i:=\newfont@last@attributes\do{%
+ \f@get@af\ff@temp@i
+ \expandafter\edef\csname ff@temp\tempb\endcsname{\tempa\space}%
+ }%
+ % Combine all \f@temp<X> into \f@name.
+ \edef\f@name{f:\ff@temp@collect}%
+ \expandafter\let\expandafter\temp \csname \f@name \endcsname
+ %
+ \ifx\temp\relax
+ \let\do\relax
+ \expandafter\xdef\csname\f@name\endcsname
+ {\do \the\dimen@ \space \newfont@mag\space {\newfont@fname}}%
+ \f@debug{^^J\the\inputlineno: Started font def with
+ "\csname \f@name\endcsname".}%
+ \else
+ \edef\newfont@size{\the\dimen@}%
+ \divide\dimen@ by1000
+ \multiply\dimen@ by\newfont@mag\relax
+ \let\newfont@prefix\empty
+ \let\do\newfont@insert
+ % Try inserting the new size.
+ \temp\relax
+ % If the new size hasn't been inserted, append it now.
+ \ifx\do\newfont@insert
+ \let\do\relax
+ \expandafter\xdef\csname\f@name\endcsname {%
+ \newfont@prefix \do \newfont@size\space \newfont@mag\space {\newfont@fname}%
+ }%
+ \f@debug{^^J\the\inputlineno: Updated font def to
+ "\csname \f@name\endcsname".}%
+ \fi
+ \fi
+}%
+%
+% \newfont@insert FONT-SIZE MAG-FACTOR FILE-NAME
+%
+% Insert new font file into the list of font files in \newfont@prefix,
+% preserving ascending order of scaled design sizes.
+%
+% Pass in new font's design size in \newfont@size, mag factor
+% in \newfont@mag, font file name in \newfont@fname, pre-computed
+% scaled size in \dimen@.
+\def\newfont@insert#1 #2 #3{%
+ \toks@=\expandafter{\newfont@prefix}%
+ % We are comparing scaled font sizes, not design sizes.
+ \dimen@ii=#1\divide\dimen@ii by1000 \multiply\dimen@ii by#2\relax
+ %
+ \ifdim \dimen@ii < \dimen@
+ % Not inserting yet, go on to the next font file.
+ \edef\newfont@prefix{\the\toks@ \noexpand\do #1 #2 {#3}}%
+ \else
+ % Time to insert the new font file. If we are adding a font file
+ % for the same design size/mag factor, the new def will override
+ % the old, but give out a warning.
+ \def\newfont@next{\noexpand\do #1 #2 {#3}}%
+ \ifnum #2=\newfont@mag
+ \ifdim #1=\newfont@size
+ \f@warning{^^J\the\inputlineno: Warning: Replacing font "#3" (#1@#2)
+ with font "\newfont@fname" (\newfont@size @\newfont@mag).}%
+ \let\newfont@next\empty
+ \fi
+ \fi
+ \edef\newfont@prefix{\the\toks@
+ \noexpand\do \newfont@size \space \newfont@mag \space {\newfont@fname}%
+ \newfont@next}%
+ % No need to parse further, just append the rest of the list.
+ \expandafter\newfont@append
+ \fi
+}%
+%
+\def\newfont@append#1\relax{%
+ \let\do\relax
+ \expandafter\xdef\csname\f@name\endcsname {\newfont@prefix #1}%
+ \f@debug{^^J\the\inputlineno: Updated font def to
+ "\csname \f@name\endcsname".}%
+}%
+%
+%
+%
+% Defining new font features and attributes.
+%
+\newcount\fcacheidx % Font cache index.
+\newcount\ffeatcount % Font feature count.
+% We'll build up the following as we add font features.
+\let\ff@reset\empty
+\let\ff@collect\empty
+\let\ff@temp@reset\empty
+\let\ff@temp@collect\empty
+%
+% \newfontattr FONTFEATURE FONTATTR
+\def\newfontattr #1 #2 {%
+ % Define a new font attribute, if it's not defined yet.
+ \expandafter\ifx\csname fa:#2\endcsname \relax
+ \else
+ \errmessage{Font attribute "#2" already defined as part
+ of font feature "\csname ff@\csname faf:#2\endcsname\endcsname"}%
+ \fi
+ \expandafter\xdef\csname fa:#2\endcsname{\the\fcacheidx}%
+ \expandafter\xdef\csname fa@\the\fcacheidx\endcsname{#2}%
+ % Invalidate current font cache (and update index for the next font
+ % attribute).
+ \global\advance\fcacheidx by1
+ %
+ % Define a new font feature, if it's not defined yet.
+ \expandafter\ifx\csname ff:#1\endcsname \relax
+ \expandafter\xdef\csname ff:#1\endcsname{\the\ffeatcount}%
+ \expandafter\xdef\csname ff@\the\ffeatcount\endcsname{#1}%
+ % Update \ff@reset to clear the new font feature cell \ffN.
+ \toks@=\expandafter{\ff@reset}%
+ \xdef\ff@reset{\the\toks@
+ \let\expandafter\noexpand\csname ff\the\ffeatcount\endcsname
+ \noexpand\empty}%
+ % Update \ff@temp@reset to clear the new font feature cell \ff@tempN.
+ \toks@=\expandafter{\ff@temp@reset}%
+ \xdef\ff@temp@reset{\the\toks@
+ \let\expandafter\noexpand\csname ff@temp\the\ffeatcount\endcsname
+ \noexpand\empty}%
+ % Update \ff@collect to include the new font feature cell \ffN.
+ \toks@=\expandafter{\ff@collect}%
+ \xdef\ff@collect{\the\toks@
+ ^^A\expandafter\noexpand\csname ff\the\ffeatcount\endcsname}%
+ % Update \ff@temp@collect to include the new font feature cell \ffN.
+ \toks@=\expandafter{\ff@temp@collect}%
+ \xdef\ff@temp@collect{\the\toks@
+ ^^A\expandafter\noexpand\csname ff@temp\the\ffeatcount\endcsname}%
+ % Set \ffN to \empty, otherwise it will be set to \relax the first
+ % time we try to access it through \csname...\endcsname, and we
+ % depend on it to be either a number or \empty.
+ \global\expandafter\let\csname ff\the\ffeatcount\endcsname \empty
+ %
+ \global\advance\ffeatcount by1
+ % We've added a new font feature, so we should invalidate current
+ % font cache. But we've already done so above when adding the new
+ % font attribute.
+ %\global\advance\fcacheidx by1
+ \fi
+ % Assign the font attribute to the font feature.
+ \expandafter\xdef\csname faf:#2\endcsname{\csname ff:#1\endcsname}%
+}%
+%
+% \newfontattrs FONTFEATURE FONTATTRIBUTE[,...]
+\def\newfontattrs #1 #2 {%
+ \for\temp:=#2\do{\newfontattr #1 {\temp} }%
+}%
+%
+%
+%
+% Setting a font.
+%
+\newcount\f@base@mag \f@base@mag=1000
+\newcount\f@count@
+% Set a font based on the current values of \ff0, \ff1, ..., or
+% execute #1 if such font is not defined.
+\def\f@setfont#1{%
+ \f@verbose{^^J\the\inputlineno: (Started search for a font.}%
+ % Check the cache.
+ \expandafter\let\expandafter\temp
+ \csname f\the\fcacheidx:\the\f@cur@size:\ff@collect\endcsname
+ \ifx\temp\relax
+ % Not in the cache.
+ \let\do\relax
+ \expandafter\let\expandafter\temp \csname f:\ff@collect\endcsname
+ \ifx\temp\relax
+ \f@debug{^^JFont is not defined.}%
+ #1% Execute the no-font action.
+ \else
+ \dimen@=\z@ % Fake previous size for the first font in the list.
+ \let\f@fname\empty
+ \let\do\f@search@size
+ \global\dimen@i=\f@cur@size
+ \temp\relax
+ \ifnum\f@base@mag=\f@count@ \else
+ \global\divide\dimen@i by\f@base@mag
+ \global\multiply\dimen@i by\f@count@
+ \fi
+ \f@debug{Found font "\f@fname", mag factor \the\f@count@,
+ scaled size \the\dimen@i.}%
+ % Save it in the cache.
+ \global \expandafter\font
+ \csname f\the\fcacheidx:\the\f@cur@size:\ff@collect\endcsname
+ \f@fname \space at\the\dimen@i
+ % Set it.
+ \csname f\the\fcacheidx:\the\f@cur@size:\ff@collect\endcsname
+ \fi
+ \else
+ % Got a cache hit.
+ \f@debug{Found font in the cache.}%
+ \temp
+ \fi
+ \f@verbose{Ended search for a font.)}%
+}%
+%
+% \f@search@size DESIGN-SIZE MAG-FACTOR FILE-NAME
+%
+% Pass in the desired font size in \dimen@i. Font file name is saved
+% in \f@fname, font's mag factor in \f@count@.
+\def\f@search@size #1 #2 #3{%
+ \f@verbose{Looking at font def "#3" (#1@#2).}%
+ \dimen@ii=\dimen@ % Get the size of the previous font from the list.
+ % Scale design size of the next font as per current base mag factor.
+ \dimen@=#1\relax
+ \ifnum#2=\f@base@mag \else
+ \divide\dimen@ by\f@base@mag \multiply\dimen@ by#2\relax
+ \fi
+ % Calculate the "dividing" point size.
+ \count@=\dimen@ % Don't clobber \dimen@.
+ \advance\count@ by-\dimen@ii % Curr size - prev size.
+ % Don't do the following line -- .3333*3pt < 1pt.
+ %\advance\dimen@ii by.3333\count@ % 1/3 of the way from prev to curr.
+ \divide\count@ by3
+ \advance\dimen@ii by\count@ sp% 1/3 of the way from prev to curr.
+ %
+ \ifdim \dimen@i > \dimen@ii
+ % The previous font's size is too small. The current font might
+ % or might not be the one we need, but we assume it is, in case
+ % it's the last one in the list.
+ \def\f@fname{#3}%
+ \f@count@=#2\relax
+ \else
+ % The target size is close enough to the prev font's size, so we take that.
+ \ifx\f@fname\empty
+ % This is the case when we need a size smaller than the very
+ % first font in the list.
+ \def\f@fname{#3}%
+ \f@count@=#2\relax
+ \fi
+ \expandafter\f@search@gobble
+ \fi
+}%
+%
+\def\f@search@gobble#1\relax{}%
+%
+%
+%
+% Font feature manipulations.
+%
+\newdimen\f@cur@size \f@cur@size=10pt
+% \setfont{ATTRS}
+\def\setfont{%
+ % Empty \ff0, \ff1, ..., \ff<ffeature_count - 1>.
+ \ff@reset
+ \addfontattrs % Substitutes and sets the font.
+}%
+%
+% \modfont{REM-FEATURES}{ADD-OR-MOD-ATTRS}
+\def\modfont#1{%
+ \unsetfontfeatures{#1}%
+ \addfontattrs % Substitutes and sets the font.
+}%
+%
+% \addfontattrs{ADD-OR-MOD-ATTRS}
+\def\addfontattrs#1{%
+ % For each feature with attribute in #1, set \ff<f> to `<a> ', where
+ % <f> is the feature index and <a> is the attribute index. For a
+ % number or a dimen in #1, set \f@cur@size. Dimen specs starting
+ % with '.' (e.g., '.1pt') are not supported.
+ \for\f@i:=#1\do{%
+ \expandafter\gobble@to@finish % Gobbles 'pt' when \f@i is '10pt'.
+ \ifnum9<1\f@i\relax
+ \finish
+ % A number or a dimen.
+ \get@dimen{\f@i}%
+ \f@cur@size=\dimen@
+ \else
+ \finish
+ % Not a number.
+ \f@get@af\f@i
+ \expandafter\edef\csname ff\tempb\endcsname {\tempa\space}%
+ \fi
+ }%
+ % Try to set the font; if it's not defined, do substitution and try
+ % to set the resulting font. Do font substitution inside a group so
+ % that the current set of font attributes is not clobbered.
+ \f@setfont{{\f@subst \f@setfont{\f@err@nofont}\expandafter}\the\font}%
+}%
+%
+% Take a dimension or a number, and save it in \dimen@. In case of a
+% number, assume `pt' units.
+\def\get@dimen#1{%
+ \afterassignment\gobble@to@finish
+ \dimen@#1pt \finish
+}%
+\def\gobble@to@finish#1\finish{}%
+%
+\def\f@err@nofont{%
+ \dumpfontfeatures
+ \errmessage{^^JFound no font def for the selected feature set}%
+}%
+%
+% \remfontfeatures{REM-FEATURES}
+\def\remfontfeatures#1{%
+ \unsetfontfeatures{#1}%
+ % Try to set the font; if it's not defined, do substitution and try
+ % to set the resulting font. Do font substitution inside a group so
+ % that the current set of font attributes is not clobbered.
+ \f@setfont{{\f@subst \f@setfont{\f@err@nofont}\expandafter}\the\font}%
+}%
+%
+\def\unsetfontfeatures#1{%
+ % Unset \ff<f> for each feature <f> in #1.
+ \for\f@i:=#1\do{%
+ \expandafter\let\expandafter\temp\csname ff:\f@i\endcsname
+ \ifx\temp\relax
+ \errmessage{Undefined font feature "\f@i"}%
+ \fi
+ \expandafter\let \csname ff\temp\endcsname \empty
+ }%
+}%
+%
+% Pretty-print the current settings of font features.
+\def\dumpfontfeatures{%
+ \message{^^J\the\inputlineno: font size \the\f@cur@size, features (}%
+ \@dumpfontfeatures\message
+ \message{).}%
+}%
+%
+\def\@dumpfontfeatures#1{%
+ \fori0\ffeatcount{%
+ \edef\temp{\csname ff\the\count@\endcsname}%
+ #1{%
+ \csname ff@\the\count@\endcsname=%
+ \ifx\temp\empty
+ <unset>%
+ \else
+ \expandafter\dump@ff\temp
+ \fi
+ }%
+ }%
+}%
+%
+\def\dump@ff#1 {\csname fa@#1\endcsname}%
+%
+%
+%
+% Construction of font filter strings.
+%
+% \fontsubstpre =MATCH-ATTR -REM-FEATURES +ADD-OR-MOD-ATTRS
+%
+% Install a new font substitution to be applied before other font
+% substitutions.
+\def\fontsubstpre{%
+ \let\fontsubst@mklist\fontsubst@pre
+ \@fontsubst
+}%
+%
+% \fontsubstpost =MATCH-ATTR -REM-FEATURES +ADD-OR-MOD-ATTRS
+%
+% Install a new font substitution to be applied after other font
+% substitutions.
+\def\fontsubstpost{%
+ \let\fontsubst@mklist\fontsubst@post
+ \@fontsubst
+}%
+%
+% \@fontsubst =MATCH-ATTR -REM-FEATURES +ADD-OR-MOD-ATTRS
+\def\@fontsubst{%
+ % Construct the match string in \fontsubst@match@list.
+ \f@mk@falist\fontsubst@\fontsubst@match@list % =MATCH-ATTR
+}%
+%
+% \fontsubst@ -REM-FEATURES +ADD-OR-MOD-ATTRS
+\def\fontsubst@{%
+ % Construct the rem string in \fontsubst@rem@list.
+ \f@mk@flist\fontsubst@@\fontsubst@rem@list % -REM-FEATURES
+}%
+%
+% \fontsubst@ +ADD-OR-MOD-ATTRS
+\def\fontsubst@@{%
+ % Construct the add string in \fontsubst@add@list.
+ \f@mk@falist\fontsubst@fin\fontsubst@add@list% +ADD-OR-MOD-ATTRS
+}%
+%
+\def\fontsubst@fin{%
+ % Add the new substitution to either head or tail of the current
+ % substitution list.
+ \let\@end\relax
+ \edef\f@subst@list{\fontsubst@mklist}%
+}%
+%
+\def\fontsubst@pre{%
+ \fontsubst@match@list \@end
+ \fontsubst@rem@list \@end
+ \fontsubst@add@list \@end
+ \f@subst@list
+}%
+%
+\def\fontsubst@post{%
+ \f@subst@list
+ \fontsubst@match@list \@end
+ \fontsubst@rem@list \@end
+ \fontsubst@add@list \@end
+}%
+%
+% Initialize the font substitution list to empty.
+\let\f@subst@list\empty
+%
+% Given the name of an attribute, return index of the attribute
+% in \tempa and index of the attribute's feature in \tempb.
+\def\f@get@af#1{%
+ % Get attribute's index.
+ \expandafter\let\expandafter\tempa\csname fa:#1\endcsname
+ \ifx\tempa\relax
+ \errmessage{Undefined font attribute "#1"}%
+ \fi
+ % Get feature index for the attribute.
+ \expandafter\let\expandafter\tempb\csname faf:#1\endcsname
+ \ifx\tempb\relax
+ \errmessage{Undefined font attribute "#1"}%
+ \fi
+}%
+%
+% Given a comma-separated list of attributes #4, construct a string
+% (saving it in macro #2) as a sequence of `F.A,' specs, where F is
+% the index of the feature to which attribute belongs, and A is the
+% index of the attribute. After that, call #1. #3 is an ignored
+% syntax sugar ("=" or "+") from the user-visible command.
+\def\f@mk@falist#1#2#3#4 {%
+ \let#2\empty % Start with a clean slate.
+ \let\do\relax
+ \for\f@i:=#4\do{%
+ \f@get@af\f@i
+ \edef#2{#2\do\tempb.\tempa,}% Append the spec to the list.
+ }%
+ #1%
+}%
+%
+% Given a comma-separated list of features #4, construct a string
+% (saving it in macro #2) as a sequence of `F,' specs, where F is the
+% feature index. After that, call #1. After that, call #1. #3 is an
+% ignored syntax sugar ("-") from the user-visible command.
+\def\f@mk@flist#1#2#3#4 {%
+ \let#2\empty
+ \let\do\relax
+ \for\f@i:=#4\do{%
+ \expandafter\let\expandafter\temp\csname ff:\f@i\endcsname
+ \ifx\temp\relax
+ \errmessage{Undefined font feature "\f@i"}%
+ \fi
+ \edef#2{#2\do\temp,}%
+ }%
+ #1%
+}%
+%
+% \fori{FROM-INCL}{TO-EXCL}{EXEC}
+\def\fori#1#2#3{%
+ \count@=#1\relax
+ \loop
+ #3\relax
+ \advance\count@ by1
+ \ifnum\count@<#2\repeat
+}%
+%
+%
+%
+% Generic filter parsing macros. Configure by defining these
+% callbacks (before running \f@run@filter on the filter string):
+%
+% \f@do@filter@match#1.#2, - match the pair filter/attribute.
+% \f@do@filter@rem - unset feature `F,'.
+% \f@do@filter@add - add the pair `F.A,'.
+% \f@hook@filter@end - action at the end of the filter (upon
+% successful match).
+% \f@hook@filter@skip - action for \f@filter@gobble@this
+% and \f@filter@gobble@all.
+%
+% To skip one filter, \f@do@filter@match can
+% call \f@filter@gobble@this. To skip all remaining filters,
+% call \f@filter@gobble@all.
+%
+% Note: Theoretically, we can use a construct like
+%
+% \csname ff@\csname faf:A\endcsname\endcsname
+%
+% to get the feature corresponding to attribute A. But this would
+% fail with an incomprehensible error message (`missing \endcsname')
+% if \csname faf:A\endcsname is undefined, so we'd have to test this
+% before each use. To avoid the overhead, we just add the font
+% feature index to the font filter.
+%
+%
+% \f@run@filter
+% [MATCH-ATTR\@end REM-FEATURES\@end ADD-OR-MOD-ATTRS\@end [...]]\relax
+\def\f@run@filter{%
+ \let\do\f@do@filter@match
+ \let\@end\f@run@filter@rem
+}%
+%
+% \f@run@filter@rem REM-FEATURES\@end ADD-OR-MOD-ATTRS\@end ... \relax
+\def\f@run@filter@rem{%
+ \let\do\f@do@filter@rem
+ \let\@end\f@run@filter@add
+}%
+%
+% \f@run@filter@add ADD-OR-MOD-ATTRS\@end ... \relax
+\def\f@run@filter@add{%
+ \let\do\f@do@filter@add
+ \let\@end\f@hook@filter@end
+}%
+%
+\def\f@filter@gobble@this#1\@end#2\@end#3\@end{\f@hook@filter@skip \f@run@filter}%
+\def\f@filter@gobble@all#1\relax{\f@hook@filter@skip}%
+%
+%
+%
+% Filter parsing callbacks for font substitution.
+%
+% Apply only the first font substitution matching the current font.
+\def\f@subst@once{%
+ \let\f@do@filter@match\f@subst@match@init
+ \let\f@do@filter@rem\f@subst@rem
+ \let\f@do@filter@add\f@subst@add
+ \let\f@hook@filter@end\f@subst@nomore
+ \let\f@hook@filter@skip\f@subst@skip
+ \expandafter\f@run@filter \f@subst@list \relax
+}%
+%
+% Apply all font substitutions in order, allowing substitutions to be
+% chained.
+\def\f@subst{%
+ \let\f@do@filter@match\f@subst@match@init
+ \let\f@do@filter@rem\f@subst@rem
+ \let\f@do@filter@add\f@subst@add
+ \let\f@hook@filter@end\f@subst@again
+ \let\f@hook@filter@skip\f@subst@skip
+ \f@verbose{^^J\the\inputlineno: (Running font substitution filter:}%
+ \expandafter\f@run@filter \f@subst@list \relax
+ \f@verbose{^^J)}%
+}%
+%
+% Match one feature.
+\def\f@subst@match@init{%
+ \f@verbose{^^J(}%
+ \let\do\f@subst@match
+ \do
+}%
+%
+\def\f@subst@match#1.#2,{%
+ \f@verbose{^^Jmatching \csname ff@#1\endcsname.\csname fa@#2\endcsname}%
+ % This funky way to compare the two numbers takes care of \ff#1
+ % being \empty. However, keep in mind that if \ff#1 is undefined,
+ % the following will make it a \relax. Space at the end of \ff#1
+ % will be gobbled by TeX, because it's a space following a number.
+ \ifnum 1#2=1\csname ff#1\endcsname \else
+ \f@verbose{^^J skipping, unmatched
+ \csname ff@#1\endcsname.\csname fa@#2\endcsname}%
+ \expandafter\f@filter@gobble@this % Skip to the next filter.
+ \fi
+}%
+%
+% Remove one feature.
+\def\f@subst@rem#1,{%
+ \f@verbose{^^Junsetting \csname ff@#1\endcsname}%
+ \expandafter\let\csname ff#1\endcsname \empty
+}%
+%
+% Add attribute #2 (which must belong to feature #1).
+\def\f@subst@add#1.#2,{%
+ \f@verbose{^^Jadding \csname ff@#1\endcsname.\csname fa@#2\endcsname}%
+ \expandafter\def\csname ff#1\endcsname{#2 }%
+}%
+%
+\def\f@subst@nomore{\f@verbose{^^J)}\f@filter@gobble@all}%
+\def\f@subst@again{\f@verbose{^^J)}\f@run@filter}%
+\def\f@subst@skip{\f@verbose{^^J)}}%
+%
+%
+%
+% Filter parsing callbacks for pretty-printing the current font filter
+% string.
+%
+% Pretty-print the current font filter string.
+\def\dumpfontfilter{\f@dump@filter\f@subst@list}%
+%
+% Pretty-print the given font filter string.
+\def\f@dump@filter#1{%
+ \let\f@do@filter@match\f@dump@match@init
+ \let\f@do@filter@rem\f@dump@rem@init
+ \let\f@do@filter@add\f@dump@add@init
+ \let\f@hook@filter@end\f@dump@again
+ \let\f@hook@filter@skip\relax
+ \message{\the\inputlineno: (Dumping font substitution filter:}%
+ \expandafter\f@run@filter #1\relax
+ \message{^^J)}%
+}%
+\def\f@dump@match@init{%
+ \message{^^J(^^J=}%
+ \def\do##1.##2,{\message{\csname ff@##1\endcsname.\csname fa@##2\endcsname}}%
+ \do
+}%
+\def\f@dump@rem@init{%
+ \message{^^J-}%
+ \def\do##1,{\message{\csname ff@##1\endcsname}}%
+ \do
+}%
+\def\f@dump@add@init{%
+ \message{^^J+}%
+ \def\do##1.##2,{\message{\csname ff@##1\endcsname.\csname fa@##2\endcsname}}%
+ \do
+}%
+\def\f@dump@again{\message{^^J)}\f@run@filter}%
+
+\endinput
+
+
+\ftracelevel=3
+
+\newfontattr family CMRoman
+\newfontattr family CMTypewriter
+\newfontattr family CMSansSerif
+\newfontattr encoding OT1
+\newfontattr encoding OML
+\newfontattr encoding OMS
+\newfontattr encoding OMX
+\newfontattr slant up
+\newfontattr slant sl
+\newfontattr slant it
+\newfontattr slant ui
+
+\fontsubstpre =CMRoman -slant +OT1
+%\dumpfontfilter
+
+\fontsubstpre =up - +CMRoman,OML
+%\dumpfontfilter
+
+\fontsubstpost =CMTypewriter -encoding +
+%\dumpfontfilter
+
+\fontsubstpost =CMRoman,up,OML -slant +OMX
+%\dumpfontfilter
+
+\fontsubstpre =it,CMTypewriter,OMX -family,encoding +OT1
+%\dumpfontfilter
+
+\fontsubstpost =CMSansSerif,ui -encoding +CMTypewriter,OMX,it
+%\dumpfontfilter
+
+\fontsubstpost =it,CMTypewriter,OMX -encoding,family +ui,OMS
+
+\dumpfontfilter
+\dumpfontfeatures
+
+%\newfont 10 cmbx10 {}
+%\message{^^J***\f@name}
+\newfont 10 1000 cmti10 CMRoman,it,OT1
+\message{^^J***\f@name}
+\newfont 10 1000 cmt10 CMRoman,OT1
+\message{^^J***\f@name}
+\newfont 12pt 1000 cmti12 CMRoman,it,OT1
+\message{^^J***\f@name}
+\newfont 10 1000 cmmi10 ui,OMS
+\message{^^J***\f@name}
+\newfont 8 1000 cmti8 CMRoman,it,OT1
+\message{^^J***\f@name}
+\newfont 11 1000 cmti11 CMRoman,it,OT1
+\message{^^J***\f@name}
+\newfont 8 1000 cmt8 CMRoman,OT1
+\message{^^J***\f@name}
+\newfont 9 1000 cmt9 CMRoman,OT1
+\message{^^J***\f@name}
+\newfont 0.2cm 1000 cmti1cm CMRoman,it,OT1
+\message{^^J***\f@name}
+\newfont 1.in 1000 cmin it,OT1
+\message{^^J***\f@name}
+\newfont 5. 1000 cmot1 OT1
+\message{^^J***\f@name}
+
+\setfont {CMRoman,it,0.3cm,OMS}% -> family=CMRoman encoding=OT1 slant=<unset>
+\dumpfontfeatures
+\setfont {CMTypewriter,it,OMX}% -> family=<unset> encoding=OT1 slant=it
+\dumpfontfeatures
+\addfontattrs {7,up}% -> family=CMRoman encoding=OT1 slant=<unset>
+\dumpfontfeatures
+\remfontfeatures{family}% -> family=<unset> encoding=OT1 slant=<unset>
+\dumpfontfeatures
+\modfont {}{CMSansSerif,ui}% -> family=<unset> encoding=OMS slant=ui
+\dumpfontfeatures
+\remfontfeatures{}% -> family=<unset> encoding=OMS slant=ui
+\dumpfontfeatures
+\addfontattrs {}% -> family=<unset> encoding=OMS slant=ui
+\dumpfontfeatures
+\modfont {}{}% -> family=<unset> encoding=OMS slant=ui
+\dumpfontfeatures
+
+\message{^^J*********************************************************}
+
+\newfontattr family TestFamily
+\newfont 5. 1000 sz5-1.0-1 TestFamily
+\message{^^J***\f@name}
+\newfont 5. 1000 sz5-1.0-2 TestFamily
+\message{^^J***\f@name}
+\newfont 5. 1400 sz5-1.4-1 TestFamily
+\message{^^J***\f@name}
+\newfont 5. 900 sz5-0.9-1 TestFamily
+\message{^^J***\f@name}
+\newfont 5. 900 sz5-0.9-2 TestFamily
+\message{^^J***\f@name}
+\newfont 5. 1400 sz5-1.4-2 TestFamily
+\message{^^J***\f@name}
+\setfont {CMRoman,9pt}% ->
+
+
+\newfont 10 1000 cmr10 CMRoman,rm,OT1
+\message{^^J***\f@name}
+
+\bye
diff --git a/contrib/texifont/fattr.tex.pairs b/contrib/texifont/fattr.tex.pairs
new file mode 100644
index 0000000..675c707
--- /dev/null
+++ b/contrib/texifont/fattr.tex.pairs
@@ -0,0 +1,644 @@
+% font set Computer Modern, Latin Modern, Bera
+% font family CMRoman, CMTypewriter, CMSansSerif
+%
+% font feature slant, weight, width
+% font attribute sl, it, bold, cond
+%
+% fontfile
+%
+% Font features and attributes:
+%
+% size design point size
+% encoding ot1, oml, oms, omx, t1, ts1, t2a
+% slant up, sl, it, ui, cursive
+% weight lt, med, semib, bold, bx,
+% width cond, normal, ext
+% figures oldfigures, liningfigures
+% caps normalcaps, allcaps, smallcaps, nocaps
+
+\input eplain
+
+\catcode`@=11
+%
+% \fsz:CMRoman/<OT1>/<up>/<med>/<normal>/<liningfigures>/<normalcaps>
+% ->
+% cmr5/5,cmr7/7,cmr8/8,cmr9/9,cmr10/10,cmr12/12,cmr17/17,.
+%
+% {CMRoman}{b}{bx}
+% {OML,CMRoman}{m}{up}
+% {OML,CMRoman}{bx}{up}
+% {OML,CMRoman}{b}{bx}
+% {CMSans}{it}{sl}
+% {CMSans}{b}{bx}
+% {CMSans,OML}{}{CMRoman}
+% {ConcreteRoman}{b}{LMSans,b}
+% {OT1,CMMath}{}{CMRoman,n}
+% {OMX,CMMath}{bx}{m}
+%
+
+%
+%
+%
+% Font-related logging. Meanings of \ftracelevel values are:
+%
+% 0 - none
+% 1 - warning
+% 2 - debug
+% 3 - verbose
+\newcount\ftracelevel
+\ftracelevel=1
+%
+\def\f@warning{\f@trace0 }%
+\def\f@debug {\f@trace1 }%
+\def\f@verbose{\f@trace2 }%
+\def\f@trace#1{%
+ \ifnum#1<\ftracelevel
+ \expandafter\message
+ \else
+ \expandafter\gobble
+ \fi
+}%
+%
+%
+%
+% Construction of font filter strings.
+%
+% \fontsubstpre{MATCH-ATTR}{REM-FEATURES}{ADD-OR-MOD-ATTRS}
+%
+% Install a new font substitution to be applied before other font
+% substitutions.
+\def\fontsubstpre{%
+ \let\fontsubst@mklist\fontsubst@pre
+ \@fontsubst
+}%
+%
+% \fontsubstpost{MATCH-ATTR}{REM-FEATURES}{ADD-OR-MOD-ATTRS}
+%
+% Install a new font substitution to be applied after other font
+% substitutions.
+\def\fontsubstpost{%
+ \let\fontsubst@mklist\fontsubst@post
+ \@fontsubst
+}%
+%
+% \@fontsubst{MATCH-ATTR}{REM-FEATURES}{ADD-OR-MOD-ATTRS}
+\def\@fontsubst{%
+ % Construct the match string in \fontsubst@match@list.
+ \f@mk@falist\fontsubst@\fontsubst@match@list%{MATCH-ATTR}
+}%
+%
+% \fontsubst@{REM-FEATURES}{ADD-OR-MOD-ATTRS}
+\def\fontsubst@{%
+ % Construct the rem string in \fontsubst@rem@list.
+ \f@mk@flist\fontsubst@@\fontsubst@rem@list%{REM-FEATURES}
+}%
+%
+% \fontsubst@{ADD-OR-MOD-ATTRS}
+\def\fontsubst@@{%
+ % Construct the add string in \fontsubst@add@list.
+ \f@mk@falist\fontsubst@fin\fontsubst@add@list%{ADD-OR-MOD-ATTRS}
+}%
+%
+\def\fontsubst@fin{%
+ % Add the new substitution to either head or tail of the current
+ % substitution list.
+ \let\@end\relax
+ \edef\f@subst@list{\fontsubst@mklist}%
+}%
+%
+\def\fontsubst@pre{%
+ \fontsubst@match@list \@end
+ \fontsubst@rem@list \@end
+ \fontsubst@add@list \@end
+ \f@subst@list
+}%
+%
+\def\fontsubst@post{%
+ \f@subst@list
+ \fontsubst@match@list \@end
+ \fontsubst@rem@list \@end
+ \fontsubst@add@list \@end
+}%
+%
+% Initialize the font substitution list to empty.
+\let\f@subst@list\empty
+%
+% Given the name of an attribute, return index of the attribute
+% in \tempa and index of the attribute's feature in \tempb.
+\def\f@get@af#1{%
+ % Get attribute's index.
+ \expandafter\let\expandafter\tempa\csname fa:#1\endcsname
+ \ifx\tempa\relax
+ \errmessage{Undefined font attribute `#1'}%
+ \fi
+ % Get feature index for the attribute.
+ \expandafter\let\expandafter\tempb\csname faf:#1\endcsname
+ \ifx\tempb\relax
+ \errmessage{Undefined font attribute `#1'}%
+ \fi
+}%
+%
+% Given a comma-separated list of attributes #3, construct a string
+% (saving it in macro #2) as a sequence of `F.A,' specs, where F is
+% the index of the feature to which attribute belongs, and A is the
+% index of the attribute. After that, call #1.
+\def\f@mk@falist#1#2#3{%
+ \let#2\empty % Start with a clean slate.
+ \let\do\relax
+ \for\f@i:=#3\do{%
+ \f@get@af\f@i
+ \edef#2{#2\do\tempb.\tempa,}% Append the spec to the list.
+ }%
+ #1%
+}%
+%
+% Given a comma-separated list of features #3, construct a string
+% (saving it in macro #2) as a sequence of `F,' specs, where F is the
+% feature index. After that, call #1.
+\def\f@mk@flist#1#2#3{%
+ \let#2\empty
+ \let\do\relax
+ \for\f@i:=#3\do{%
+ \expandafter\let\expandafter\temp\csname ff:\f@i\endcsname
+ \ifx\temp\relax
+ \errmessage{Undefined font feature `\f@i'}%
+ \fi
+ \edef#2{#2\do\temp,}%
+ }%
+ #1%
+}%
+%
+% \fori{FROM-INCL}{TO-EXCL}{EXEC}
+\def\fori#1#2#3{%
+ \count@=#1\relax
+ \loop
+ #3\relax
+ \advance\count@ by1
+ \ifnum\count@<#2\repeat
+}%
+%
+%
+%
+% Font feature manipulations.
+%
+% \setfont{ATTRS}
+\def\setfont{%
+ % Empty \ff0, \ff1, ..., \ff<ffeature_count - 1>.
+ \ff@reset
+ \addfontattrs % Substitutes and sets the font.
+}%
+%
+% \modfont{REM-FEATURES}{ADD-OR-MOD-ATTRS}
+\def\modfont#1{%
+ \unsetfontfeatures{#1}%
+ \addfontattrs % Substitutes and sets the font.
+}%
+%
+% \addfontattrs{ADD-OR-MOD-ATTRS}
+\def\addfontattrs#1{%
+ % For each feature with attribute in #1, set \ff<f> to <a>, where
+ % <f> is the feature index and <a> is the attribute index.
+ \for\f@i:=#1\do{%
+ \f@get@af\f@i
+ \expandafter\let\csname ff\tempb\endcsname \tempa
+ }%
+ % Substitute the font.
+ \f@subst
+ % Set the font, if we've found one.
+}%
+%
+% \remfontfeatures{REM-FEATURES}
+\def\remfontfeatures#1{%
+ \unsetfontfeatures{#1}%
+ % Substitute the font.
+ \f@subst
+ % Set the font, if we've found one.
+}%
+%
+\def\unsetfontfeatures#1{%
+ % Unset \ff<f> for each feature <f> in #1.
+ \for\f@i:=#1\do{%
+ \expandafter\let\expandafter\temp\csname ff:\f@i\endcsname
+ \ifx\temp\relax
+ \errmessage{Undefined font feature `\f@i'}%
+ \fi
+ \expandafter\let \csname ff\temp\endcsname \empty
+ }%
+}%
+%
+% Pretty-print the current settings of font features.
+\def\dumpfontfeatures{%
+ \def\fa@{}% This will be used for features which are not set,
+ % for which \ffN is \empty.
+ \message{^^JCurrent font features: (}%
+ \fori0\ffeatcount{\message{%
+ \csname ff@\the\count@\endcsname.%
+ \expandafter\dump@ff\expandafter{\csname ff\the\count@\endcsname}}}%
+ \message{)}%
+}%
+\def\dump@ff#1{\csname fa@#1\endcsname}%
+%
+%
+%
+% Generic filter parsing macros. Configure by defining these
+% callbacks (before running \f@run@filter on the filter string):
+%
+% \f@do@filter@match#1.#2, - match the pair filter/attribute
+% \f@do@filter@rem - unset feature `F,'
+% \f@do@filter@add - add the pair `F.A,'
+% \f@end@filter@add - action at the end of the filter.
+%
+% We could avoid adding font feature together with an attribute and
+% use a construct like \csname ff@\csname faf:A\endcsname\endcsname
+% to get the feature corresponding to attribute A. But this would
+% fail with an incomprehensible error message (`missing \endcsname')
+% if \csname faf:A\endcsname is undefined, so we'd have to test this
+% before each use. To avoid the overhead, we just add the font
+% feature index to the font filter.
+%
+% \f@run@filter
+% [MATCH-ATTR\@end REM-FEATURES\@end ADD-OR-MOD-ATTRS\@end [...]]\relax
+\def\f@run@filter{%
+ \let\do\f@do@filter@match
+ \let\@end\f@run@filter@rem
+}%
+\def\f@run@filter@again{\f@verbose{^^J)}\f@run@filter}%
+%
+% \f@run@filter@rem REM-FEATURES\@end ADD-OR-MOD-ATTRS\@end ... \relax
+\def\f@run@filter@rem{%
+ \let\do\f@do@filter@rem
+ \let\@end\f@run@filter@add
+}%
+%
+% \f@run@filter@add ADD-OR-MOD-ATTRS\@end ... \relax
+\def\f@run@filter@add{%
+ \let\do\f@do@filter@add
+ \let\@end\f@end@filter@add
+}%
+%
+\def\f@filter@gobble@this#1\@end#2\@end#3\@end{\f@run@filter@again}%
+\def\f@filter@gobble@all#1\relax{}%
+%
+%
+%
+% Filter parsing callbacks for font substitution.
+%
+% Apply only the first font substitution matching the current font.
+\def\f@subst@once{%
+ \let\f@do@filter@match\f@subst@match@init
+ \let\f@do@filter@rem\f@subst@rem
+ \let\f@do@filter@add\f@subst@add
+ \let\f@end@filter@add\f@subst@nomore
+ \expandafter\f@run@filter \f@subst@list \relax
+}%
+%
+% Apply all font substitutions in order, allowing substitutions to be
+% chained.
+\def\f@subst{%
+ \let\f@do@filter@match\f@subst@match@init
+ \let\f@do@filter@rem\f@subst@rem
+ \let\f@do@filter@add\f@subst@add
+ \let\f@end@filter@add\f@run@filter@again
+ \expandafter\f@run@filter \f@subst@list \relax
+}%
+%
+% Match one feature.
+\def\f@subst@match@init{%
+ \f@verbose{^^J(}%
+ \let\do\f@subst@match
+ \do
+}%
+%
+\def\f@subst@match#1.#2,{%
+ \f@verbose{^^Jmatching \csname ff@#1\endcsname.\csname fa@#2\endcsname}%
+ % This funky way to compare the two numbers takes care of \ff#1
+ % being \empty. However, keep in mind that if \ff#1 is undefined,
+ % the following will make it a \relax.
+ \ifnum 1#2=1\csname ff#1\endcsname \else
+ \f@verbose{^^J skipping unmatched
+ \csname ff@#1\endcsname.\csname fa@#2\endcsname}%
+ \expandafter\f@filter@gobble@this % Skip to the next filter.
+ \fi
+}%
+%
+% Remove one feature.
+\def\f@subst@rem#1,{%
+ \f@verbose{^^Junsetting \csname ff@#1\endcsname}%
+ \expandafter\let\csname ff#1\endcsname \empty
+}%
+%
+% Add attribute #2 (which must belong to feature #1).
+\def\f@subst@add#1.#2,{%
+ \f@verbose{^^Jadding \csname ff@#1\endcsname.\csname fa@#2\endcsname}%
+ \expandafter\def\csname ff#1\endcsname{#2}%
+}%
+%
+\def\f@subst@nomore{\f@verbose{^^J)}\f@filter@gobble@all}%
+%
+%
+%
+% Filter parsing callbacks for pretty-printing the current font filter
+% string.
+%
+%\def\dumpfontfilter{%
+%}%
+% Pretty-print the current font filter string.
+\def\dumpfontfilter{\f@dump@filter\f@subst@list}%
+%
+% Pretty-print the given font filter string.
+\def\f@dump@filter#1{%
+ \message{^^J(}%
+ \let\do\space
+ \expandafter\f@dump@filter@#1\relax
+}%
+%
+\def\f@dump@filter@#1\@end#2\@end#3\@end#4\relax{%
+ \message{^^J=#1^^J-#2^^J+#3^^J}%
+ \def\temp{#4}%
+ \ifx\temp\empty
+ \message{^^J)}%
+ \expandafter\f@filter@gobble@all
+ \else
+ \expandafter\f@dump@filter@
+ \fi
+ #4\relax
+}%
+%
+%
+%
+% Defining new font features.
+%
+\newcount\fcacheidx % Font cache index.
+\newcount\ffeatcount % Font feature count.
+\let\ff@reset\empty % We'll build this up as we add font features.
+%
+% \newfontattr FONTFEATURE FONTATTR
+\def\newfontattr #1 #2 {%
+ % Define a new font attribute, if it's not defined yet.
+ \expandafter\ifx\csname fa:#2\endcsname \relax
+ \else
+ \errmessage{Font attribute `#2' already defined as part
+ of font feature `\csname ff@\csname faf:#2\endcsname\endcsname'}%
+ \fi
+ \expandafter\xdef\csname fa:#2\endcsname{\the\fcacheidx}%
+ \expandafter\xdef\csname fa@\the\fcacheidx\endcsname{#2}%
+ % Invalidate current font cache (and update index for the next font
+ % attribute).
+ \global\advance\fcacheidx by1
+ %
+ % Define a new font feature, if it's not defined yet.
+ \expandafter\ifx\csname ff:#1\endcsname \relax
+ \expandafter\xdef\csname ff:#1\endcsname{\the\ffeatcount}%
+ \expandafter\xdef\csname ff@\the\ffeatcount\endcsname{#1}%
+ % Update \ff@reset to clear the new font feature cell \ffN.
+ \toks@=\expandafter{\ff@reset}%
+ \xdef\ff@reset{\the\toks@
+ \let\expandafter\noexpand\csname ff\the\ffeatcount\endcsname
+ \noexpand\empty}%
+ % Set \ffN to \empty, otherwise it will be set to \relax the first
+ % time we try to access it through \csname...\endcsname, and we
+ % depend on it to be either a number or \empty.
+ \global\expandafter\let\csname ff\the\ffeatcount\endcsname \empty
+ %
+ \global\advance\ffeatcount by1
+ % We've added a new font feature, so we should invalidate current
+ % font cache. But we've already done so above when adding the new
+ % font attribute.
+ %\global\advance\fcacheidx by1
+ \fi
+ % Assign the font attribute to the font feature.
+ \expandafter\xdef\csname faf:#2\endcsname{\csname ff:#1\endcsname}%
+}%
+%
+% \newfontfamily FONTSET FONTFAMILY
+\def\newfontfamily #1 #2 {%
+ \f@def{fset}{#1}{ffam}{#2}{Font family}%
+ \f@defadd{fset:#1}{#2}%
+}%
+%
+% \f@def {PARENT-PREFIX} {PARENT-NAME} {CHILD-PREFIX} {CHILD-NAME} {CHILD-DESCR}
+\def\f@def#1#2#3#4#5{%
+ % Define parent.
+ \expandafter\gdef\csname #1:#2\endcsname
+ \expandafter\ifx\csname#1:#2\endcsname\relax
+ \expandafter\gdef\csname#1:#2\endcsname{}%
+ \else
+ \let\do\space
+ \errmessage{#3 #2 already defined as `\csname#1:#2\endcsname'}%
+ \fi
+}%
+
+
+
+\ftracelevel=3
+
+\newfontattr family CMRoman
+\newfontattr family CMTypewriter
+\newfontattr family CMSansSerif
+\newfontattr encoding OT1
+\newfontattr encoding OML
+\newfontattr encoding OMS
+\newfontattr encoding OMX
+\newfontattr slant up
+\newfontattr slant sl
+\newfontattr slant it
+\newfontattr slant ui
+
+%\expandafter\def\csname ff:family\endcsname{0}%
+%\expandafter\def\csname ff:encoding\endcsname{1}%
+%\expandafter\def\csname ff:slant\endcsname{2}%
+%
+%\expandafter\def\csname fa:CMRoman\endcsname{0}%
+%\expandafter\def\csname fa:CMTypewriter\endcsname{1}%
+%\expandafter\def\csname fa:CMSansSerif\endcsname{2}%
+%
+%\expandafter\def\csname fa:OT1\endcsname{3}%
+%\expandafter\def\csname fa:OML\endcsname{4}%
+%\expandafter\def\csname fa:OMS\endcsname{5}%
+%\expandafter\def\csname fa:OMX\endcsname{6}%
+%
+%\expandafter\def\csname fa:up\endcsname{7}%
+%\expandafter\def\csname fa:sl\endcsname{8}%
+%\expandafter\def\csname fa:it\endcsname{9}%
+%\expandafter\def\csname fa:ui\endcsname{10}%
+%
+%\ffeatcount=3
+%\fattrcount=11
+%
+%\expandafter\def\csname faf:CMRoman\endcsname{0}%
+%\expandafter\def\csname faf:CMTypewriter\endcsname{0}%
+%\expandafter\def\csname faf:CMSansSerif\endcsname{0}%
+%
+%\expandafter\def\csname faf:OT1\endcsname{1}%
+%\expandafter\def\csname faf:OML\endcsname{1}%
+%\expandafter\def\csname faf:OMS\endcsname{1}%
+%\expandafter\def\csname faf:OMX\endcsname{1}%
+%
+%\expandafter\def\csname faf:up\endcsname{2}%
+%\expandafter\def\csname faf:sl\endcsname{2}%
+%\expandafter\def\csname faf:it\endcsname{2}%
+%\expandafter\def\csname faf:ui\endcsname{2}%
+
+\let\do\relax
+
+\fontsubstpre{CMRoman}{slant}{OT1}
+\message{^^J\f@subst@list}
+
+\fontsubstpre{up}{}{CMRoman,OML}
+\message{^^J\f@subst@list}
+
+\fontsubstpost{CMSansSerif}{}{OMX}
+\message{^^J\f@subst@list}
+
+\fontsubstpost{CMTypewriter}{encoding}{}
+\message{^^J\f@subst@list}
+
+\fontsubstpost{CMRoman,up,OML}{slant}{OT1}
+\message{^^J\f@subst@list}
+
+\fontsubstpre{it,CMTypewriter,OMX}{family,encoding}{OT1}
+\message{^^J\f@subst@list}
+
+\fontsubstpost{it,CMTypewriter,OMX}{encoding,family}{ui,OMS}
+\message{^^J\f@subst@list}
+
+% 0.0, 2.9, 1.5
+\setfont{CMRoman,it,OMS}% -> , 4, 9
+\dumpfontfeatures
+% 0.1, 2.9, 1.5
+%\setfont{CMTypewriter,it,OMS}% -> 1, , 9
+%% 0.2, 2.9, 1.5
+%\setfont{CMSansSerif,it,OMS}% -> 2, 6, 9
+%% 0.1, 2.9, 1.6
+%\setfont{CMTypewriter,it,OMX}% -> , 5, 10
+%% 0.0, 2.7, 1.3
+%\setfont{CMRoman,up,OT1}% -> , 4, 7
+% 0.0, 2.7, 1.4
+%\setfont{CMRoman,up,OML}% -> 0, 3,
+\dumpfontfilter
+
+
+%% 0.0, 2.9, 1.4
+%\setfont{CMRoman,it,OML}% -> , 4, 9
+%\dumpffs
+%\modfont{}{CMTypewriter}% -> 1, 4, 9 -> 1, , 9
+%\dumpffs
+%\modfont{slant}{ui,CMSansSerif}% -> 2, , 10 ->
+%\dumpffs
+
+\bye
+
+
+
+% \setfont{CMRoman,b,sl}
+% \modfont{}{up} % CMRoman,b,up
+
+
+\def\test{ii,iv,iii,i}
+\def\i{0}
+\def\ii{1}
+\def\iii{2}
+\def\iv{3}
+
+\count0=2147483647
+\count@=-1
+
+% \f@sort{MAX-ITEM-IDX}{ITEMS}{ITEM-CS-PREFIX}
+\def\f@sort#1#2#3{%
+ \let\f@sorted\empty
+ % Empty \f@sort0, \f@sort1, ..., \f@sort<MAX-ITEM-IDX>.
+ \fori{0}{#1}{\expandafter\let\csname f@sort\the\count@\endcsname \empty}%
+ % Set \f@sort<X>, where <X> is the value of \<ITEM-CS-PREFIX><ITEM>.
+ \for\f@sort@i:=#2\do{%
+ \expandafter\edef\csname f@sort\csname#3\f@sort@i\endcsname\endcsname{%
+ \csname \f@sort@i\endcsname,%
+ }%
+ }%
+ % Combine all \f@sort<X> into \f@sorted.
+ \fori{0}{#1}{%
+ \edef\f@sorted{%
+ \f@sorted
+ \csname f@sort\the\count@\endcsname
+ }%
+ }%
+}%
+
+\f@sort{4}{\test}{}
+\show\f@sorted
+\bye
+
+
+
+
+% \f@def {PREFIX} {NAME} {DESCR}
+\f@def#1#2#3{%
+ \expandafter\ifx\csname#1:#2\endcsname\relax
+ \expandafter\gdef\csname#1:#2\endcsname{}%
+ \else
+ \let\do\space
+ \errmessage{#3 #2 already defined as `\csname#1:#2\endcsname'}%
+ \fi
+}%
+
+% \f@defadd {PARENT} {CHILD}
+\f@defadd#1#2{%
+ \let\do\relax
+ \expandafter\edef\expandafter\temp\expandafter{%
+ \csname #1\endcsname \do #2}%
+ \global\expandafter\let\csname #1\endcsname \temp
+}%
+
+% \newfontset FONTSET
+\def\newfontset #1 {%
+ \f@def{fset}{#1}{Font set}
+}%
+
+% \newfontfamily FONTSET FONTFAMILY
+\def\newfontfamily #1 #2 {%
+ \f@def{ffam}{#2}{Font family}%
+ \f@defadd{fset:#1}{#2}%
+}%
+
+% \newfontfeature FONTFEATURE
+\def\newfontfeature #1 {%
+ \f@def{ff}{#1}{Font feature}%
+}%
+
+% \newfontattr FONTFEATURE FONTATTR
+\def\newfontattr #1 #2 {%
+ \f@def{fa}{#2}{Font attribute}%
+ \f@defadd{ff:#1}{#2}%
+}%
+
+% \newfont FONTFAMILY SIZE ENCODING ATTRIBUTES
+\def\newfont #1 #2 #3 #4 {%
+}%
+
+\def\f@addattrchar#1#2{%
+\bgroup
+ \uccode`a=#2%
+ \uppercase{%
+\egroup
+ \xdef#1{a#1}%
+ }%
+}%
+
+\def\fori#1#2#3{%
+ \count@=#1\relax
+ \loop
+ #3\relax
+ \advance\count@ by1
+ \ifnum\count@<#2\repeat
+}%
+
+\def\f@resetattrs#1{%
+ \gdef#1{fa:}%
+ \fori{0}{20}{\f@addattrchar#1{`\*}}%
+}%
+
+\newcount\numfontfeatures
+
+\f@resetattrs\f@attributes
+\show\f@attributes
+
+\bye
diff --git a/contrib/texifont/fdefs.tex b/contrib/texifont/fdefs.tex
new file mode 100644
index 0000000..a16eac5
--- /dev/null
+++ b/contrib/texifont/fdefs.tex
@@ -0,0 +1,176 @@
+\input fattr
+\ftracelevel=4
+
+\newfontattrs encoding OT1,OMS,OML,OMX,T1,TS1,T2A
+\newfontattrs slant upright,slanted,italic,unitalic,cursive
+\newfontattrs weight light,medium,semibold,bold,boldext
+\newfontattrs figstyle oldfigs,liningfigs
+\newfontattrs caps normalcaps,capssmallcaps,allcaps,nocaps
+
+%
+%
+%\newfont 1000 aoeu 12.3 aa,b,c
+%\newfont 1000 hhth 83.6pt
+%\newfont 1000 xufd 24.8
+%
+%\newfont 1000 huxo 8.3pt dd
+%\newfont 1000 ofeo 35.4
+%\newfont 1000 ixqe 217pt
+%
+%\newfont 1000 huxo 9pt {}
+%\newfont 1000 ofeo 2pt
+%\newfont 1000 ixqe 4
+%\bye
+%
+%
+
+
+%
+% Computer Modern Roman.
+%
+\newfontattr family CMRoman
+% Medium weight.
+% Upright.
+\newfont 1000 cmr5 5 CMRoman,OT1,upright,medium,liningfigs,normalcaps
+\newfont 1000 cmr6 6 {}
+\newfont 1000 cmr7 7 {}
+\newfont 1000 cmr8 8 {}
+\newfont 1000 cmr9 9 {}
+\newfont 1000 cmr10 10 {}
+\newfont 1000 cmr12 12 {}
+\newfont 1000 cmr17 17 {}
+% Italic.
+\newfont 1000 cmti7 7 CMRoman,OT1,italic,medium,liningfigs,normalcaps
+\newfont 1000 cmti8 8 {}
+\newfont 1000 cmti9 9 {}
+\newfont 1000 cmti10 10 {}
+\newfont 1000 cmti12 12 {}
+% Slanted.
+\newfont 1000 cmsl6 6 CMRoman,OT1,slanted,medium,liningfigs,normalcaps % From cmextra.
+\newfont 1000 cmsl8 8 {}
+\newfont 1000 cmsl9 9 {}
+\newfont 1000 cmsl10 10 {}
+\newfont 1000 cmsl12 12 {}
+% Caps and small caps.
+\newfont 1000 cmcsc10 10 CMRoman,OT1,upright,medium,liningfigs,capssmallcaps
+% Unslanted italic (for slanted pound sterling).
+\newfont 1000 cmu10 10 CMRoman,OT1,unitalic,medium,liningfigs,normalcaps
+%
+% Bold weight.
+\newfont 1000 cmb10 10 CMRoman,OT1,upright,bold,liningfigs,normalcaps
+\fontsubstpost =CMRoman,bold - +boldext
+%
+% Bold extended.
+% Upright.
+\newfont 1000 cmbx5 5 CMRoman,OT1,upright,boldext,liningfigs,normalcaps
+\newfont 1000 cmbx6 6 {}
+\newfont 1000 cmbx7 7 {}
+\newfont 1000 cmbx8 8 {}
+\newfont 1000 cmbx9 9 {}
+\newfont 1000 cmbx10 10 {}
+\newfont 1000 cmbx12 12 {}
+% Italic.
+\newfont 1000 cmbxti7 7 CMRoman,OT1,italic,boldext,liningfigs,normalcaps % from cmextra
+\newfont 1000 cmbxti10 10 {}
+\newfont 1000 cmbxti12 12 {} % from cmextra
+% Slanted.
+\newfont 1000 cmbxsl10 10 CMRoman,OT1,slanted,boldext,liningfigs,normalcaps
+%
+% Math letters.
+\fontsubstpost =CMRoman,OML - +upright
+\fontsubstpost =CMRoman,OML - +oldfigs
+% Medium weight.
+\newfont 1000 cmmi5 5 CMRoman,OML,upright,medium,oldfigs,normalcaps
+\newfont 1000 cmmi6 6 {}
+\newfont 1000 cmmi7 7 {}
+\newfont 1000 cmmi8 8 {}
+\newfont 1000 cmmi9 9 {}
+\newfont 1000 cmmi10 10 {}
+\newfont 1000 cmmi12 12 {}
+% Bold extended.
+\newfont 1000 cmmib5 5 CMRoman,OML,upright,boldext,oldfigs,normalcaps
+\newfont 1000 cmmib6 6 {}
+\newfont 1000 cmmib7 7 {}
+\newfont 1000 cmmib8 8 {}
+\newfont 1000 cmmib9 9 {}
+\newfont 1000 cmmib10 10 {}
+%
+% Math symbols.
+\fontsubstpost =CMRoman,OMS - +upright
+% Medium weight.
+\newfont 1000 cmsy5 5 CMRoman,OMS,upright,medium
+\newfont 1000 cmsy6 6 {}
+\newfont 1000 cmsy7 7 {}
+\newfont 1000 cmsy8 8 {}
+\newfont 1000 cmsy9 9 {}
+\newfont 1000 cmsy10 10 {}
+% Bold extended.
+\newfont 1000 cmbsy5 5 CMRoman,OMS,upright,boldext
+\newfont 1000 cmbsy6 6 {}
+\newfont 1000 cmbsy7 7 {}
+\newfont 1000 cmbsy8 8 {}
+\newfont 1000 cmbsy9 9 {}
+\newfont 1000 cmbsy10 10 {}
+%
+% Computer Modern Sans.
+%
+\newfontattr family CMSans
+\fontsubstpost =CMSans,OML - +CMRoman
+\fontsubstpost =CMSans,OMS - +CMRoman
+\fontsubstpost =CMSans,italic - +slanted
+\fontsubstpost =CMSans,bold - +boldext
+% Medium weight.
+% Upright.
+\newfont 1000 cmss8 8 CMSans,OT1,upright,medium,liningfigs,normalcaps
+\newfont 1000 cmss9 9 {}
+\newfont 1000 cmss10 10 {}
+\newfont 1000 cmss12 12 {}
+\newfont 1000 cmss17 17 {}
+% Slanted.
+\newfont 1000 cmssi8 8 CMSans,OT1,slanted,medium,liningfigs,normalcaps
+\newfont 1000 cmssi9 9 {}
+\newfont 1000 cmssi10 10 {}
+\newfont 1000 cmssi12 12 {}
+\newfont 1000 cmssi17 17 {}
+%
+% Bold extended.
+\newfont 1000 cmssbx10 10 CMSans,OT1,upright,boldext,liningfigs,normalcaps
+\newfont 1000 cmssbxo10 10 CMSans,OT1,slanted,boldext,liningfigs,normalcaps % from cmextra
+%
+% Computer Modern Typewriter.
+%
+\newfontattr family CMMono
+\fontsubstpost =CMMono,OML - +CMRoman,oldfigs
+\fontsubstpost =CMMono,OMS - +CMRoman
+% Medium weight.
+% Upright.
+\newfont 1000 cmtt8 8 CMMono,OT1,upright,medium,liningfigs,normalcaps
+\newfont 1000 cmtt9 9 {}
+\newfont 1000 cmtt10 10 {}
+\newfont 1000 cmtt12 12 {}
+% Italic.
+\newfont 1000 cmitt9 9 CMMono,OT1,italic,medium,liningfigs,normalcaps % from cmextra
+\newfont 1000 cmitt10 10 {}
+\newfont 1000 cmitt12 12 {} % from cmextra
+% Slanted.
+\newfont 1000 cmsltt9 9 CMMono,OT1,slanted,medium,liningfigs,normalcaps % from cmextra
+\newfont 1000 cmsltt10 10 {}
+
+
+\setfont{OML,CMRoman,upright,medium,liningfigs,normalcaps}
+
+ABCabcdf
+
+\addfontattrs{CMMono}
+\dumpfontfeatures
+ABCabcdf
+
+\addfontattrs{CMRoman}
+\dumpfontfeatures
+ABCabcdf
+
+\addfontattrs{OT1}
+\dumpfontfeatures
+ABCabcdf
+
+\bye
diff --git a/contrib/texifont/fsel.tex b/contrib/texifont/fsel.tex
new file mode 100644
index 0000000..332ff60
--- /dev/null
+++ b/contrib/texifont/fsel.tex
@@ -0,0 +1,1703 @@
+%
+% These are in Texinfo.
+%
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+%
+\def\gobble#1{}%
+\def\linenumber{l.\the\inputlineno:\space}%
+\newlinechar = `^^J
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}%
+\def\strutheightpercent{.70833}%
+\def\strutdepthpercent {.29167}%
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}%
+%
+% End of Texinfo defs.
+%
+% Specify amount and type of font-related logging:
+% 0 notifications and warnings go to the log file only;
+% 1 only warning go to the console;
+% 2 notifications and warnings go to the console;
+% 3 notifications go to the console, all warnings are made into errors.
+%
+% In all cases notifications and warnings go to the log file.
+\newcount\tracingfonts
+\tracingfonts1
+%
+\def\fontnotify{%
+ \ifcase\tracingfonts
+ \expandafter\wlog
+ \or % 1
+ \expandafter\wlog
+ \else % 2-...
+ \expandafter\message
+ \fi
+}%
+%
+\def\fontwarn{%
+ \ifcase\tracingfonts
+ \expandafter\wlog
+ \or % 1
+ \expandafter\message
+ \or % 2
+ \expandafter\message
+ \else % 3-...
+ \expandafter\errmessage
+ \fi
+}%
+%
+% We will sometimes temporarily turn these off (e.g., to avoid
+% \message and \setbox interfering with \accent).
+\let\@setleading\setleading
+\let\@fontnotify\fontnotify
+\let\@fontwarn\fontwarn
+% Font and shape identification strings.
+\def\shape@string{\f@encoding/\f@family/\f@series/\f@shape}%
+\def\font@string{\shape@string/\f@size:\base@fntscale}%
+%
+% \declarefontfamily FAMILY FACTOR LINESKIP
+%
+% Declare font FAMILY, and set it's scale FACTOR (relative to the
+% Computer Modern family) and LINESKIP factor (which will be applied
+% to the current font size to obtain basic baseline skip). Every font
+% family must be declared before any font declaration \declarefont
+% using that family.
+\def\declarefontfamily#1 #2 #3 {%
+ % Warn if the family has already been declared.
+ \expandafter \ifx \csname fam@scale/#1\endcsname\relax \else
+ \fontwarn{^^JWarning: redeclaring font family `#1'.}%
+ \fi
+ \expandafter\def\csname fam@scale/#1\endcsname{#2}%
+ \expandafter\def\csname fam@lskip/#1\endcsname{#3}%
+ % Initialize the family's encoding list to an empty list.
+ \expandafter\let \csname fam@enc@list/#1\endcsname \empty
+}%
+%
+% \declaremathfontfamily FAMILY FACTOR LINESKIP TEXTENC L-SKEW S-SKEW
+%
+% Declare math font family. Parameters:
+%
+% FAMILY font family name;
+% FACTOR scale factor (relative to the Computer Modern family);
+% LINESKIP lineskip factor (which will be applied to the current
+% font size to obtain basic baseline skip);
+% TEXTENC font encoding to use for the family 0 (this is to
+% distinguish fonts with T1 and OT1 encodings for the
+% `text' font, since T1 and OT1 have accents in
+% different slots);
+% L-SKEW skew char for family 1 (math letters);
+% S-SKEW skew char for family 2 (math symbols).
+\def\declaremathfontfamily#1 #2 #3 #4 #5 #6 {%
+ \declarefontfamily #1 #2 #3
+ \expandafter\def\csname fam@textenc/#1\endcsname{#4}%
+ \expandafter\def\csname fam@ml-sc/#1\endcsname{#5}%
+ \expandafter\def\csname fam@ms-sc/#1\endcsname{#6}%
+}%
+%
+% \mathfontfamilyhook FAMILY {TEXT}
+%
+% Define a hook to be called every time the fonts for math FAMILY are
+% set up.
+\def\mathfontfamilyhook#1 #2{%
+ \expandafter\def\csname fmath@hook@#1\endcsname{#2}%
+}%
+%
+% \mathfontfamilyprehook FAMILY {TEXT}
+%
+% Define a hook to be called when the math FAMILY is loaded.
+\def\mathfontfamilyprehook#1 #2{%
+ \expandafter\def\csname fmath@pre-hook@#1\endcsname{#2}%
+}%
+%
+% \mathfontfamilyposthook FAMILY {TEXT}
+%
+% Define a hook to be called when the math FAMILY is unloaded.
+\def\mathfontfamilyposthook#1 #2{%
+ \expandafter\def\csname fmath@post-hook@#1\endcsname{#2}%
+}%
+%
+% \fontbasefamily FAMILY
+%
+% Declare FAMILY as the "base" family, which means that its fonts
+% will be displayed at their "natural" sizes, and all other families
+% will be scaled to match FAMILY.
+\def\fontbasefamily#1 {%
+ % Check that the family has been declared.
+ \expandafter \ifx \csname fam@scale/#1\endcsname\relax
+ \errmessage{Error: setting base family to an unknown family `#1'}%
+ \fi
+ \edef\base@fntscale{\csname fam@scale/#1\endcsname}%
+ % Reload the current font (it may change if the base factor changed).
+ \selectfont
+}%
+%
+% \fontfamily STYLE FAMILY
+%
+% FIXME doc.
+\def\mathword{math}%
+\let\f@family@math\empty % Avoid `Undefined' errors in \csname the first time.
+\def\fontfamily#1 #2 {%
+ \edef\temp{#1}%
+ \ifx\temp\mathword
+ % Call post-hook for the old math family.
+ \csname fmath@post-hook@\f@family@math\endcsname
+ \expandafter\edef \csname f@family@\mathword\endcsname{#2}%
+ % Define accents for the encoding of the \fam0 font.
+ \expandafter\csname \csname fam@textenc/#2\endcsname @math@textenc\endcsname
+ % FIXME Need to call \resetmathfonts now, or call pre-hook after
+ % the first call to \resetmathfonts, otherwise errors are possible
+ % about undefined glyphs.
+ % Call pre-hook for the new math family.
+ \csname fmath@pre-hook@#2\endcsname
+ \else
+ \expandafter\edef \csname f@family@#1\endcsname{#2}%
+ \fi
+}%
+%
+% FIXME Rename.
+\def\selectfont@style#1{%
+ \expandafter\let\expandafter \f@family \csname f@family@#1\endcsname
+ \selectfont
+}%
+%
+% \declarefont ENC FAMILY SER SH L-U SZ FONT
+%
+% Declare a FAMILY font in ENC encoding, SER series and SH shape, for
+% the size range L-U. SZ is the design size of the font, FONT is the
+% font file name. L-U defines the size range as [L,U). All sizes (L,
+% U, SZ) may contain optional unit specifier; if it is missing, `pt'
+% is assumed.
+\def\declarefont #1 #2 #3 #4 #5-#6 #7 #8 {%
+ % Check that FAMILY has been declared.
+ \expandafter \ifx \csname fam@scale/#2\endcsname\relax
+ \errmessage{Error: declaring font `#8' for an unknown family `#2'}%
+ \fi
+ % Convert all sizes into integers, scaled 10 times.
+ \fnt@size@to@int{#5}\edef\tempa{\number\dimen@}% L
+ \fnt@size@to@int{#6}\edef\tempb{\number\dimen@}% U
+ \fnt@size@to@int{#7}\edef\tempc{\number\dimen@}% SZ
+ % Construct internal font shape name as \sh/ENC/FAMILY/SER/SH.
+ \expandafter\def\expandafter\temp\expandafter{%
+ \csname sh/#1/#2/#3/#4\endcsname
+ }%
+ % Add the font specification as the quad L U SZ FONT to the
+ % beginning of the font list for this shape.
+ \expandafter\ifx\temp\relax
+ \let\tempd\empty
+ \else
+ \edef\tempd{\temp}% Previous def of the shape name.
+ \fi
+ \expandafter\edef\temp{\tempa\space\tempb\space\tempc\space#8 \tempd}%
+ % Add the encoding to the list of encodings for this family, if it's
+ % not been added yet.
+ \expandafter\ifx \csname fam@enc/#2/#1\endcsname \relax
+ \expandafter\let\expandafter\temp \csname fam@enc@list/#2\endcsname
+ \expandafter\edef \csname fam@enc@list/#2\endcsname{\temp\space #1}%
+ \fi
+ % Set the flag that this family supports this encoding.
+ \expandafter\let\csname fam@enc/#2/#1\endcsname\empty
+}%
+%
+% \fontmap ENC1 FAM1 SER1 SH1 > ENC2 FAM2 SER2 SH2
+%
+% Define font mapping. Ideally, any of the attributes can be an `*',
+% but only a useful subset is currently supported for the first half
+% (see \search@font@map). It should be easy to extend this subset if
+% need be.
+%
+% If an `*' appears in the first half (`from-attributes'), its
+% meaning is "apply this map to fonts having anything for this
+% attribute". If an `*' appears in the second half (`to-attributes'),
+% its meaning is "leave this attribute unchanged from the respective
+% from-attribute".
+%
+% E1 F1 S1 s1 > E2 F2 S2 s2
+\def\fontmap#1 #2 #3 #4 > #5 #6 #7 #8 {%
+ \expandafter\def\csname fmap/#1/#2/#3/#4\endcsname{#5/#6/#7/#8}%
+}%
+%
+% \fontmapshape FAMILY1 SH1 > FAMILY2 SH2
+%
+% Define generic shape mapping: requests for FAMILY1 fonts in shape
+% SH1 and any encoding and series will be redirected to FAMILY2 fonts
+% in shape SH2 and the same encoding and series.
+\def\fontmapshape#1 #2 > #3 #4 {%
+ \fontmap * #1 * #2 > * #3 * #4
+}%
+%
+% \fontmapseries FAMILY1 SER1 > FAMILY2 SER2
+%
+% Define generic series mapping: requests for FAMILY1 fonts in series
+% SER1 and any encoding and shape will be redirected to FAMILY2 fonts
+% in series SER2 and the same encoding and shape.
+\def\fontmapseries#1 #2 > #3 #4 {%
+ \fontmap * #1 #2 * > * #3 #4 *
+}%
+%
+% \fontmapfamily FAMILY1 ENC FAMILY2
+%
+% Define family mapping: requests for FAMILY1 fonts in encoding ENC
+% will be redirected to FAMILY2 fonts in the same encoding.
+\def\fontmapfamily#1 #2 #3 {%
+ \fontmap #2 #1 * * > * #3 * *
+ % Remember that this family supports this encoding.
+ \expandafter\let\csname fam@enc/#1/#2\endcsname\empty
+}%
+%
+% Take a dimension or a number (in which case assume `pt' units) and
+% convert it into an integer (in \dimen@) ten times the dimension's
+% representation in points. We attempt to round properly, to the
+% extent that TeX's integer arithmetics allows. Note that we take
+% 0.1pt = 6554 (6553.6 rounded to the nearest integer), but maybe
+% 6553 would have been better because it rounds the 100ths of a point
+% better (e.g., in 10.85pt), for which we care more than for the
+% 1000ths / 10000ths of a point (e.g., in 10.849pt).
+\def\fnt@size@to@int#1{%
+ \get@dimen{#1}%
+ \advance\dimen@ by.05pt % 0.1pt / 2.
+ \divide\dimen@ by6554 % = 0.1pt = (Xpt / 0.1pt * 0.1pt) * 10 / 1pt.
+}%
+% Take a dimension or a number, and save it in \dimen@. In case of a
+% number, assume `pt' units.
+\def\get@dimen#1{%
+ \afterassignment\gobble@to@finish
+ \dimen@#1pt \finish
+}%
+\def\gobble@to@finish#1\finish{}%
+%
+% These generally should not be used by the end user. To actually
+% select the font specified by one or several of the following, say
+% \selectfont.
+\def\setfontencoding{\edef\f@encoding}%
+\def\setfontfamily{\edef\f@family}%
+\def\setfontseries{\edef\f@series}%
+\def\setfontshape{\edef\f@shape}%
+\def\setfontsize#1{\fnt@size@to@int{#1}\edef\f@size{\number\dimen@}}%
+% User-space commands to set (some of) the above.
+\def\mdseries{\setfontseries{m}\selectfont}%
+\def\bfseries{\setfontseries{bx}\selectfont}%
+\def\upshape{\setfontshape{n}\selectfont}%
+\def\itshape{\setfontshape{it}\selectfont}%
+\def\slshape{\setfontshape{sl}\selectfont}%
+\def\scshape{\setfontshape{sc}\selectfont}%
+%
+% Scale \f@size.
+\def\scale@f@size#1{%
+ \scalecount\f@size{#1}%
+ \edef\f@size{\number\count@}%
+}%
+% Scale the current font. #1 is the magnification factor.
+\def\scalefont#1{%
+ \scale@f@size{#1}%
+ \selectfont
+}%
+% Scale current font size by #1. Result in \dimen@ (in points).
+% Clobbers \dimen@.
+\def\scalefontsize#1{%
+ \scalecount\f@size{#1}%
+ \dimen@=\count@\p@
+ \divide\dimen@ by10
+}%
+% Scale integer #1 by #2, taking care of the rounding. Result in
+% \count@.
+\def\scalecount#1#2{%
+ \count@#1%
+ \multiply\count@ by#2%
+ \advance\count@ by500%
+ \divide\count@ by1000
+}%
+%
+% Parameters for math fonts.
+%
+% FIXME These parameters probably have to be per-font-family.
+\def\mf@scr@factor{700 }%
+\def\mf@scrscr@factor{500 }%
+% Theoretically, these have to be per-font-family, but practically
+% plain TeX settings work with most families; and for families with
+% which these don't work (PXMath, TXMath, CharterMath, ArevMath) these
+% settings are still the best possible -- do these families have a bug
+% (or maybe some weird design decisions)?
+\def\big@factor{850 }%
+\def\Big@factor{1150 }%
+\def\bigg@factor{1450 }%
+\def\Bigg@factor{1750 }%
+%
+% Setup math fonts. This is called for every math mode switch from
+% \everymath. Texinfo doesn't use display math, so we don't bother
+% with \everydisplay. NOTE: One alternative to setting math fonts at
+% the beginning of every math mode is to set them at every change of a
+% font attribute which affects math fonts (i.e., size, series, but
+% _not_ shape). This would mean that lots of fonts will be loaded,
+% while in most cases the user will never use math with those settings.
+\everymath{\resetmathfonts}%
+\def\resetmathfonts{%
+ % Save all current font attributes -- we'll clobber them.
+ \let\reset@f@encoding\f@encoding
+ \let\reset@f@family\f@family
+ \let\reset@f@series\f@series
+ \let\reset@f@shape\f@shape
+ \let\reset@f@size\f@size
+ \let\reset@fontwarn\@fontwarn
+ % Don't report non-existent fonts -- we'll ignore them and hope that
+ % the user won't use them.
+ \let\@fontwarn\gobble
+ % Set math families for the style switches.
+ \selectmathfont@style{roman}\rmfam
+ \selectmathfont@style{sans}\sffam
+ \selectmathfont@style{mono}\ttfam
+ \let\f@family\reset@f@family
+ \itshape \setup@m@family\itfam
+ \slshape \setup@m@family\slfam
+ \setfontshape{n}\bfseries \setup@m@family\bffam
+ % Restore warnings.
+ \let\@fontwarn\reset@fontwarn
+ % Now set the math fonts. The shape is always a `.'.
+ \let\f@family\f@family@math
+ \let\f@series\reset@f@series
+ \def\f@shape{.}%
+ % Text size.
+ \setup@m@families\textfont
+ % Script size.
+ \scale@f@size\mf@scr@factor
+ \setup@m@families\scriptfont
+ % Script-script size.
+ \let\f@size\reset@f@size
+ \scale@f@size\mf@scrscr@factor
+ \setup@m@families\scriptscriptfont
+ % Call the fonts hook for this family.
+ \let\f@size\reset@f@size
+ \csname fmath@hook@\f@family@math\endcsname
+ % Restore font attributes.
+ \let\f@encoding\reset@f@encoding
+ \let\f@family\reset@f@family
+ \let\f@series\reset@f@series
+ \let\f@shape\reset@f@shape
+ \let\f@size\reset@f@size
+ \selectfont
+}%
+%
+% Select style #1 and set math family #2 to the font. FIXME Rename.
+\def\selectmathfont@style#1#2{%
+ \selectfont@style{#1}%
+ \setup@m@family{#2}%
+}%
+% Set \textfont of math family #1 to \c@font@command, unless the
+% font command is \relax.
+\def\setup@m@family#1{%
+ \expandafter\ifx\c@font@command\relax\else
+ \textfont#1=\c@font@command
+ \fi
+}%
+% Set up #1 (\textfont, \scriptfont or \scriptscriptfont) fonts for
+% families 0, 1, 2 and 3 with the current size. \f@family must be set
+% to the math font family.
+\def\setup@m@families#1{%
+ \setfontencoding{\csname fam@textenc/\f@family\endcsname}\search@font
+ #10=\c@font@command
+ \setfontencoding{OML}\search@font #11 = \c@font@command
+ \skewchar\c@font@command = \csname fam@ml-sc/\f@family\endcsname
+ \setfontencoding{OMS}\search@font #12 = \c@font@command
+ \skewchar\c@font@command = \csname fam@ms-sc/\f@family\endcsname
+ \setfontencoding{OMX}\search@font #13 = \c@font@command
+}%
+%
+% We need separate \rmfam -- math fonts define their own "text" fonts
+% which they use for the accents, and the user's "roman" family should
+% not interfere with that.
+\newfam\rmfam
+\def\rm{\selectfont@style{roman}\fam=\rmfam}%
+\newfam\sffam % \sffam is not in plain TeX.
+\def\sf{\selectfont@style{sans}\fam=\sffam}%
+\let\li = \sf % Sometimes we call it \li, not \sf.
+\def\tt{\selectfont@style{mono}\fam=\ttfam}%
+\def\it{\itshape \fam=\itfam}%
+\def\sl{\slshape \fam=\slfam}%
+\def\bf{\bfseries \fam=\bffam}%
+% We don't need math for this font style.
+\def\ttsl{\setfontshape{sl}\selectfont@style{mono}}%
+%
+\def\@big#1#2{%
+ {\hbox{$
+ \expandafter\scalefontsize \csname#1@factor\endcsname
+ \left#2\vbox to\dimen@{}\right.\n@space
+ $}}%
+}%
+\def\big{\@big{big}}%
+\def\Big{\@big{Big}}%
+\def\bigg{\@big{bigg}}%
+\def\Bigg{\@big{Bigg}}%
+%
+% The accents are in different slots in OT1 and T1, so these will
+% redefine the accents (see \setfontfamily).
+\expandafter\def\csname OT1@math@textenc\endcsname{%
+ \def\acute{\mathaccent"7013 }%
+ \def\grave{\mathaccent"7012 }%
+ \def\ddot{\mathaccent"707F }%
+ \def\tilde{\mathaccent"707E }%
+ \def\bar{\mathaccent"7016 }%
+ \def\breve{\mathaccent"7015 }%
+ \def\check{\mathaccent"7014 }%
+ \def\hat{\mathaccent"705E }%
+ \def\dot{\mathaccent"705F }%
+}%
+\expandafter\def\csname T1@math@textenc\endcsname{%
+ \def\acute{\mathaccent"7001 }%
+ \def\grave{\mathaccent"7000 }%
+ \def\ddot{\mathaccent"7004 }%
+ \def\tilde{\mathaccent"7003 }%
+ \def\bar{\mathaccent"7009 }%
+ \def\breve{\mathaccent"7008 }%
+ \def\check{\mathaccent"7007 }%
+ \def\hat{\mathaccent"7002 }%
+ \def\dot{\mathaccent"700A }%
+}%
+%
+% We keep track of the combinations of current encoding list (set by
+% @documentencoding) and current font family encoding list, for the
+% sake of glyph caching.
+\newcount\enclist@curr
+\newcount\enclist@count
+%
+\def\update@enclist@index{%
+ \expandafter\let\expandafter\temp \csname fam@enc@list/\f@family\endcsname
+ \edef\temp{\f@encoding/\cur@fenc@list/\temp}%
+ \expandafter\ifx \csname el@\temp\endcsname \relax
+ \global\advance \enclist@count by1
+ \expandafter\xdef \csname el@\temp\endcsname {\the\enclist@count}%
+ \enclist@curr=\enclist@count\relax
+ \else
+ \enclist@curr=\csname el@\temp\endcsname\relax
+ \fi
+}%
+%
+% \selectfont
+%
+% Select the font as specified by the values of \f@... and set line
+% skip and strut box for the font's size.
+\def\selectfont{%
+ \search@font
+ \c@font@command % Select the font.
+ \update@enclist@index % For proper glyph caching.
+ % Set strutbox and line skips accordingly.
+ \ifx\temp\relax\else
+ % The code below only produces lineskips which are multiples of
+ % 0.1pt. The maximum dimension it can deal with is 214.7pt. This
+ % means that, for a font with the relative factor of 1000 and the
+ % lineskip factor of 1200, the maximum font size is 178.9pt (which
+ % is 214.7pt / 1.2), which should be more than enough for Texinfo.
+ \count@\csname fam@lskip/\f@family\endcsname % This family's lineskip factor.
+ \multiply\count@ by\f@size % Requested font size (in pt, x10).
+ \multiply\count@ by\csname fam@scale/\f@family\endcsname % This family's factor.
+ \divide\count@ by\base@fntscale % Base factor.
+ \advance\count@ by500 % For the rounding.
+ \divide\count@ by1000
+ \dimen@\count@ pt
+ \divide\dimen@ by10
+ \@fontnotify{^^J\linenumber Setting line skip to \the\dimen@.}%
+ \@setleading\dimen@
+ \fi
+}%
+%
+\def\search@font{%
+ % Expand \font@string once now, we might use it several times.
+ \edef\c@font@string{\font@string}%
+ % Also define a shortcut for the corresponding font command.
+ \edef\c@font@command{\expandafter\noexpand \csname\c@font@string\endcsname}%
+ % First check if the requested font is in the cache.
+ \expandafter\let\expandafter \temp \c@font@command
+ \ifx\temp\relax
+ % No, it's not in the cache, search for the font.
+ \search@font@size
+ \expandafter\let\expandafter \temp \c@font@command
+ \ifx\temp\relax
+ % The font is not found, check whether it is mapped.
+ \search@font@map
+ \expandafter\let\expandafter \temp \c@font@command
+ \ifx\temp\relax
+ % No, it's not mapped either, issue a warning.
+ \@fontwarn{^^J\linenumber Warning: font \c@font@string\space
+ is not declared, leaving the font unchanged.}%
+ \fi
+ \fi
+ \else
+ % The font is in the cache, report it.
+ \@fontnotify{^^J\linenumber In font cache: \c@font@string\space
+ (\fontname\csname\c@font@string\endcsname).}%
+ \fi
+}%
+%
+% Search for the font as specified by the values of \f@... If it's
+% found, load it and add it to the cache.
+\def\search@font@size{%
+ % Check that there's a definition for the requested font shape
+ % (declared by \declarefont).
+ \expandafter\let\expandafter \temp \csname sh/\shape@string\endcsname
+ \ifx\temp\relax \else
+ % The shape was defined. It should contain mapping of size ranges
+ % to fonts. Search the font for the requested size.
+ \expandafter\parse@font@range\temp\finish
+ \fi
+}%
+% L U SZ FN the-rest-of-the-list
+\def\parse@font@range#1 #2 #3 #4 #5\finish{%
+ % See if we have not yet reached the end of the list.
+ \def\temp{#5}%
+ \ifx\temp\empty
+ \let\next\gobble % Yeah, the end, gobble \finish below.
+ \else
+ \let\next\parse@font@range % No, continue recursively.
+ \fi
+ % If \f@size belongs in [#1,#2), we have found our range.
+ \ifnum\f@size<#1 \else \ifnum\f@size<#2
+ \load@font{#4}{#3}%
+ \let\next\gobble@to@finish % Stop the recursive list search.
+ \fi\fi
+ \next#5\finish
+}%
+%
+% Load the font as specified by \f@... and add it to the cache. #1 is
+% the font file name, #2 is the design size.
+\def\load@font#1#2{%
+ % Calculate the scale factor for this font. Because of the way we
+ % do this, the maximum possible font size, for a font with the
+ % relative factor of 1000, is 214.7pt, which should be more than
+ % enough for Texinfo.
+ \count@ \csname fam@scale/\f@family\endcsname % This family's factor.
+ \multiply\count@ by\f@size % Requested size.
+ \multiply\count@ by1000
+ \divide\count@ by#2 % This font's design size.
+ \divide\count@ by\base@fntscale % Base factor.
+ % Report the font.
+ \@fontnotify{^^J\linenumber Adding to font cache:
+ \c@font@string \space -> #1 scaled \the\count@.}%
+ % Load it. The name we define will be used in "cache" lookups of
+ % this font.
+ \global\expandafter\font \c@font@command #1 scaled \count@\relax
+}%
+%
+% Search font mappings for the requested font (as per the \f@...
+% macros) and set \c@font@command if it's found. Mappings can contain
+% globbing characters (`*'), but for the from-attributes, we only
+% support a subset of possible combinations, see the comments below.
+% To-attributes can have any combination of `*'s.
+\def\search@font@map{%
+ % * F1 * s1
+ \if\fmap@exists *\f@family*\f@shape
+ \else
+ % * F1 S1 *
+ \if\fmap@exists *\f@family\f@series*%
+ \else
+ % ENC F1 S1 *
+ \if\fmap@exists \f@encoding\f@family\f@series*%
+ \else
+ % ENC F1 * *
+ \if\fmap@exists \f@encoding\f@family**%
+ \fi
+ \fi
+ \fi
+ \fi
+}%
+%
+% Note: calls \font@apply@map if the map exists.
+\def\fmap@exists#1#2#3#4{%
+ TT\fi % Cancel out the preceding \if -- we'll roll our own.
+ \expandafter\let\expandafter\@fmap \csname fmap/#1/#2/#3/#4\endcsname
+ \ifx\@fmap\relax
+ \fmap@exists@false
+ \else
+ \@fontnotify{^^J\linenumber Mapping font: #1/#2/#3/#4 -> \@fmap.}%
+ \expandafter\font@apply@map \@fmap\finish
+ \fmap@exists@true
+ \fi
+}%
+\def\fmap@exists@false{\expandafter\iffalse}%
+\def\fmap@exists@true{\expandafter\iftrue}%
+%
+\def\font@apply@map#1/#2/#3/#4\finish{%
+ \begingroup % Save the \f@... and \c@font@... macros.
+ \font@set@attrib \f@encoding{#1}%
+ \font@set@attrib \f@family {#2}%
+ \font@set@attrib \f@series {#3}%
+ \font@set@attrib \f@shape {#4}%
+ \selectfont
+ \global\expandafter\let\expandafter \gtemp \c@font@command
+ \endgroup % Restore the \f@... and \c@font@... macros.
+ % Define the font selection command for the new font.
+ \global\expandafter\let \c@font@command \gtemp
+}%
+%
+\def\asteriskword{*}%
+%
+\def\font@set@attrib#1#2{%
+ \edef\temp{#2}%
+ \ifx\temp\asteriskword
+ % Leave the attribute unchanged.
+ \else
+ \let#1\temp
+ \fi
+}%
+%
+% Computer Modern Roman.
+%
+\declarefontfamily CMRoman 1000 1200
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont OT1 CMRoman m n 0-5.5 5 cmr5
+\declarefont OT1 CMRoman m n 5.5-6.5 6 cmr6
+\declarefont OT1 CMRoman m n 6.5-7.5 7 cmr7
+\declarefont OT1 CMRoman m n 7.5-8.5 8 cmr8
+\declarefont OT1 CMRoman m n 8.5-9.5 9 cmr9
+\declarefont OT1 CMRoman m n 9.5-10.5 10 cmr10
+\declarefont OT1 CMRoman m n 10.5-14 12 cmr12
+\declarefont OT1 CMRoman m n 14-10000 17 cmr17
+% Italic.
+\declarefont OT1 CMRoman m it 0-7.5 7 cmti7
+\declarefont OT1 CMRoman m it 7.5-8.5 8 cmti8
+\declarefont OT1 CMRoman m it 8.5-9.5 9 cmti9
+\declarefont OT1 CMRoman m it 9.5-10.5 10 cmti10
+\declarefont OT1 CMRoman m it 10.5-10000 12 cmti12
+% Slanted.
+\declarefont OT1 CMRoman m sl 0-6.8 6 cmsl6 % from cmextra
+\declarefont OT1 CMRoman m sl 6.8-8.5 8 cmsl8
+\declarefont OT1 CMRoman m sl 8.5-9.5 9 cmsl9
+\declarefont OT1 CMRoman m sl 9.5-10.5 10 cmsl10
+\declarefont OT1 CMRoman m sl 10.5-10000 12 cmsl12
+% Caps and small caps.
+\declarefont OT1 CMRoman m sc 0-10000 10 cmcsc10
+% Unslanted italic (for slanted pound sterling).
+\declarefont OT1 CMRoman m ui 0-10000 10 cmu10
+%
+% Bold weight.
+\declarefont OT1 CMRoman b n 0-10000 10 cmb10
+\fontmapseries CMRoman b > * bx
+%
+% Bold extended.
+% Upright. ser sh [l,u) sz font
+\declarefont OT1 CMRoman bx n 0-5.5 5 cmbx5
+\declarefont OT1 CMRoman bx n 5.5-6.5 6 cmbx6
+\declarefont OT1 CMRoman bx n 6.5-7.5 7 cmbx7
+\declarefont OT1 CMRoman bx n 7.5-8.5 8 cmbx8
+\declarefont OT1 CMRoman bx n 8.5-9.5 9 cmbx9
+\declarefont OT1 CMRoman bx n 9.5-10.5 10 cmbx10
+\declarefont OT1 CMRoman bx n 10.5-10000 12 cmbx12
+% Italic.
+\declarefont OT1 CMRoman bx it 0-8.5 7 cmbxti7 % from cmextra
+\declarefont OT1 CMRoman bx it 8.5-11 10 cmbxti10
+\declarefont OT1 CMRoman bx it 11-10000 12 cmbxti12 % from cmextra
+% Slanted.
+\declarefont OT1 CMRoman bx sl 0-10000 10 cmbxsl10
+%
+% Math letters.
+\fontmap OML CMRoman m * > * * * n
+\fontmap OML CMRoman bx * > * * * n
+\fontmap OML CMRoman b * > * * bx *
+% Medium weight. ser sh [l,u) sz font
+\declarefont OML CMRoman m n 0-5.5 5 cmmi5
+\declarefont OML CMRoman m n 5.5-6.5 6 cmmi6
+\declarefont OML CMRoman m n 6.5-7.5 7 cmmi7
+\declarefont OML CMRoman m n 7.5-8.5 8 cmmi8
+\declarefont OML CMRoman m n 8.5-9.5 9 cmmi9
+\declarefont OML CMRoman m n 9.5-10.5 10 cmmi10
+\declarefont OML CMRoman m n 10.5-10000 12 cmmi12
+% Bold extended.
+\declarefont OML CMRoman bx n 0-5.5 5 cmmib5
+\declarefont OML CMRoman bx n 5.5-6.5 6 cmmib6
+\declarefont OML CMRoman bx n 6.5-7.5 7 cmmib7
+\declarefont OML CMRoman bx n 7.5-8.5 8 cmmib8
+\declarefont OML CMRoman bx n 8.5-9.5 9 cmmib9
+\declarefont OML CMRoman bx n 9.5-10000 10 cmmib10
+%
+% Math symbols.
+\fontmap OMS CMRoman m * > * * * n
+\fontmap OMS CMRoman bx * > * * * n
+\fontmap OMS CMRoman b * > * * bx *
+% Medium weight. ser sh [l,u) sz font
+\declarefont OMS CMRoman m n 0-5.5 5 cmsy5
+\declarefont OMS CMRoman m n 5.5-6.5 6 cmsy6
+\declarefont OMS CMRoman m n 6.5-7.5 7 cmsy7
+\declarefont OMS CMRoman m n 7.5-8.5 8 cmsy8
+\declarefont OMS CMRoman m n 8.5-9.5 9 cmsy9
+\declarefont OMS CMRoman m n 9.5-10000 10 cmsy10
+% Bold extended.
+\declarefont OMS CMRoman bx n 0-5.5 5 cmbsy5
+\declarefont OMS CMRoman bx n 5.5-6.5 6 cmbsy6
+\declarefont OMS CMRoman bx n 6.5-7.5 7 cmbsy7
+\declarefont OMS CMRoman bx n 7.5-8.5 8 cmbsy8
+\declarefont OMS CMRoman bx n 8.5-9.5 9 cmbsy9
+\declarefont OMS CMRoman bx n 9.5-10000 10 cmbsy10
+%
+% Computer Modern Sans.
+%
+\declarefontfamily CMSans 1000 1200
+\fontmapshape CMSans it > * sl
+\fontmapseries CMSans b > * bx
+\fontmapfamily CMSans OML CMRoman
+\fontmapfamily CMSans OMS CMRoman
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont OT1 CMSans m n 0-8.5 8 cmss8
+\declarefont OT1 CMSans m n 8.5-9.5 9 cmss9
+\declarefont OT1 CMSans m n 9.5-10.5 10 cmss10
+\declarefont OT1 CMSans m n 10.5-14 12 cmss12
+\declarefont OT1 CMSans m n 14-10000 17 cmss17
+% Slanted.
+\declarefont OT1 CMSans m sl 0-8.5 8 cmssi8
+\declarefont OT1 CMSans m sl 8.5-9.5 9 cmssi9
+\declarefont OT1 CMSans m sl 9.5-10.5 10 cmssi10
+\declarefont OT1 CMSans m sl 10.5-14 12 cmssi12
+\declarefont OT1 CMSans m sl 14-10000 17 cmssi17
+%
+% Bold extended.
+\declarefont OT1 CMSans bx n 0-10000 10 cmssbx10
+\declarefont OT1 CMSans bx sl 0-10000 10 cmssbxo10 % from cmextra
+%
+% Computer Modern Typewriter.
+%
+\declarefontfamily CMMono 1000 1200
+\fontmapfamily CMMono OML CMRoman
+\fontmapfamily CMMono OMS CMRoman
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont OT1 CMMono m n 0-8.5 8 cmtt8
+\declarefont OT1 CMMono m n 8.5-9.5 9 cmtt9
+\declarefont OT1 CMMono m n 9.5-10.5 10 cmtt10
+\declarefont OT1 CMMono m n 10.5-10000 12 cmtt12
+% Italic.
+\declarefont OT1 CMMono m it 0-9.5 9 cmitt9 % from cmextra
+\declarefont OT1 CMMono m it 9.5-10.5 10 cmitt10
+\declarefont OT1 CMMono m it 10.5-10000 12 cmitt12 % from cmextra
+% Slanted.
+\declarefont OT1 CMMono m sl 0-9.5 9 cmsltt9 % from cmextra
+\declarefont OT1 CMMono m sl 9.5-10000 10 cmsltt10
+%
+% Latin Modern Roman.
+%
+\declarefontfamily LMRoman 1000 1200
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont T1 LMRoman m n 0-5.5 5 ec-lmr5
+\declarefont T1 LMRoman m n 5.5-6.5 6 ec-lmr6
+\declarefont T1 LMRoman m n 6.5-7.5 7 ec-lmr7
+\declarefont T1 LMRoman m n 7.5-8.5 8 ec-lmr8
+\declarefont T1 LMRoman m n 8.5-9.5 9 ec-lmr9
+\declarefont T1 LMRoman m n 9.5-10.5 10 ec-lmr10
+\declarefont T1 LMRoman m n 10.5-14 12 ec-lmr12
+\declarefont T1 LMRoman m n 14-10000 17 ec-lmr17
+\declarefont TS1 LMRoman m n 0-5.5 5 ts1-lmr5
+\declarefont TS1 LMRoman m n 5.5-6.5 6 ts1-lmr6
+\declarefont TS1 LMRoman m n 6.5-7.5 7 ts1-lmr7
+\declarefont TS1 LMRoman m n 7.5-8.5 8 ts1-lmr8
+\declarefont TS1 LMRoman m n 8.5-9.5 9 ts1-lmr9
+\declarefont TS1 LMRoman m n 9.5-10.5 10 ts1-lmr10
+\declarefont TS1 LMRoman m n 10.5-14 12 ts1-lmr12
+\declarefont TS1 LMRoman m n 14-10000 17 ts1-lmr17
+% Italic.
+\declarefont T1 LMRoman m it 0-7.5 7 ec-lmri7
+\declarefont T1 LMRoman m it 7.5-8.5 8 ec-lmri8
+\declarefont T1 LMRoman m it 8.5-9.5 9 ec-lmri9
+\declarefont T1 LMRoman m it 9.5-10.5 10 ec-lmri10
+\declarefont T1 LMRoman m it 10.5-10000 12 ec-lmri12
+\declarefont TS1 LMRoman m it 0-7.5 7 ts1-lmri7
+\declarefont TS1 LMRoman m it 7.5-8.5 8 ts1-lmri8
+\declarefont TS1 LMRoman m it 8.5-9.5 9 ts1-lmri9
+\declarefont TS1 LMRoman m it 9.5-10.5 10 ts1-lmri10
+\declarefont TS1 LMRoman m it 10.5-10000 12 ts1-lmri12
+% Slanted.
+\declarefont T1 LMRoman m sl 6.8-8.5 8 ec-lmro8
+\declarefont T1 LMRoman m sl 8.5-9.5 9 ec-lmro9
+\declarefont T1 LMRoman m sl 9.5-10.5 10 ec-lmro10
+\declarefont T1 LMRoman m sl 10.5-14 12 ec-lmro12
+\declarefont T1 LMRoman m sl 14-10000 17 ec-lmro17
+\declarefont TS1 LMRoman m sl 6.8-8.5 8 ts1-lmro8
+\declarefont TS1 LMRoman m sl 8.5-9.5 9 ts1-lmro9
+\declarefont TS1 LMRoman m sl 9.5-10.5 10 ts1-lmro10
+\declarefont TS1 LMRoman m sl 10.5-14 12 ts1-lmro12
+\declarefont TS1 LMRoman m sl 14-10000 17 ts1-lmro17
+% Caps and small caps.
+\declarefont T1 LMRoman m sc 0-10000 10 ec-lmcsc10
+\declarefont TS1 LMRoman m sc 0-10000 10 ts1-lmcsc10
+%
+% Bold weight.
+\declarefont T1 LMRoman b n 0-10000 10 ec-lmb10
+\fontmapseries LMRoman b > * bx % For the `it' shape.
+\declarefont T1 LMRoman b sl 0-10000 10 ec-lmbo10
+\declarefont TS1 LMRoman b n 0-10000 10 ts1-lmb10
+\declarefont TS1 LMRoman b sl 0-10000 10 ts1-lmbo10
+%
+% Bold extended.
+% Upright. ser sh [l,u) sz font
+\declarefont T1 LMRoman bx n 0-5.5 5 ec-lmbx5
+\declarefont T1 LMRoman bx n 5.5-6.5 6 ec-lmbx6
+\declarefont T1 LMRoman bx n 6.5-7.5 7 ec-lmbx7
+\declarefont T1 LMRoman bx n 7.5-8.5 8 ec-lmbx8
+\declarefont T1 LMRoman bx n 8.5-9.5 9 ec-lmbx9
+\declarefont T1 LMRoman bx n 9.5-10.5 10 ec-lmbx10
+\declarefont T1 LMRoman bx n 10.5-10000 12 ec-lmbx12
+\declarefont TS1 LMRoman bx n 0-5.5 5 ts1-lmbx5
+\declarefont TS1 LMRoman bx n 5.5-6.5 6 ts1-lmbx6
+\declarefont TS1 LMRoman bx n 6.5-7.5 7 ts1-lmbx7
+\declarefont TS1 LMRoman bx n 7.5-8.5 8 ts1-lmbx8
+\declarefont TS1 LMRoman bx n 8.5-9.5 9 ts1-lmbx9
+\declarefont TS1 LMRoman bx n 9.5-10.5 10 ts1-lmbx10
+\declarefont TS1 LMRoman bx n 10.5-10000 12 ts1-lmbx12
+% Italic.
+\declarefont T1 LMRoman bx it 0-10000 10 ec-lmbxi10
+\declarefont TS1 LMRoman bx it 0-10000 10 ts1-lmbxi10
+% Slanted.
+\declarefont T1 LMRoman bx sl 0-10000 10 ec-lmbxo10
+\declarefont TS1 LMRoman bx sl 0-10000 10 ts1-lmbxo10
+%
+% Latin Modern Sans.
+%
+\declarefontfamily LMSans 1000 1200
+\fontmapshape LMSans it > * sl
+\fontmapseries LMSans b > * bx
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont T1 LMSans m n 0-8.5 8 ec-lmss8
+\declarefont T1 LMSans m n 8.5-9.5 9 ec-lmss9
+\declarefont T1 LMSans m n 9.5-10.5 10 ec-lmss10
+\declarefont T1 LMSans m n 10.5-14 12 ec-lmss12
+\declarefont T1 LMSans m n 14-10000 17 ec-lmss17
+% Slanted.
+\declarefont T1 LMSans m sl 0-8.5 8 ec-lmsso8
+\declarefont T1 LMSans m sl 8.5-9.5 9 ec-lmsso9
+\declarefont T1 LMSans m sl 9.5-10.5 10 ec-lmsso10
+\declarefont T1 LMSans m sl 10.5-14 12 ec-lmsso12
+\declarefont T1 LMSans m sl 14-10000 17 ec-lmsso17
+%
+% Bold extended.
+\declarefont T1 LMSans bx n 0-10000 10 ec-lmssbx10
+\declarefont T1 LMSans bx sl 0-10000 10 ec-lmssbo10
+%
+% Latin Modern Typewriter.
+%
+\declarefontfamily LMMono 1000 1200
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont T1 LMMono m n 0-8.5 8 ec-lmtt8
+\declarefont T1 LMMono m n 8.5-9.5 9 ec-lmtt9
+\declarefont T1 LMMono m n 9.5-10.5 10 ec-lmtt10
+\declarefont T1 LMMono m n 10.5-10000 12 ec-lmtt12
+% Italic.
+\declarefont T1 LMMono m it 0-10000 10 ec-lmtti10
+% Slanted.
+\declarefont T1 LMMono m sl 0-10000 10 ec-lmtto10
+%
+% Computer Modern Bright.
+%
+\declarefontfamily CMBright 1000 1250
+\fontmapshape CMBright it > * sl
+\fontmapseries CMBright bx > * sb
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont T1 CMBright m n 0-8.5 8 ebmr8
+\declarefont T1 CMBright m n 8.5-9.5 9 ebmr9
+\declarefont T1 CMBright m n 9.5-14 10 ebmr10
+\declarefont T1 CMBright m n 14-10000 17 ebmr17
+% Slanted.
+\declarefont T1 CMBright m sl 0-8.5 8 ebmo8
+\declarefont T1 CMBright m sl 8.5-9.5 9 ebmo9
+\declarefont T1 CMBright m sl 9.5-14 10 ebmo10
+\declarefont T1 CMBright m sl 14-10000 17 ebmo17
+%
+% Semi-bold weight.
+% Upright.
+\declarefont T1 CMBright sb n 0-8.5 8 ebsr8
+\declarefont T1 CMBright sb n 8.5-9.5 9 ebsr9
+\declarefont T1 CMBright sb n 9.5-14 10 ebsr10
+\declarefont T1 CMBright sb n 14-10000 17 ebsr17
+% Slanted.
+\declarefont T1 CMBright sb sl 0-8.5 8 ebso8
+\declarefont T1 CMBright sb sl 8.5-9.5 9 ebso9
+\declarefont T1 CMBright sb sl 9.5-14 10 ebso10
+\declarefont T1 CMBright sb sl 14-10000 17 ebso17
+%
+% Bold extended.
+\declarefont T1 CMBright bx n 0-10000 10 ebbx10
+%
+% Computer Modern Bright Typewriter.
+%
+\declarefontfamily CMBrightMono 1000 1250
+\fontmapshape CMBrightMono it > * sl
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 CMBrightMono m n 0-10000 10 ebtl10
+\declarefont T1 CMBrightMono m sl 0-10000 10 ebto10
+%
+% European Concrete Roman.
+%
+\declarefontfamily ConcreteRoman 1000 1250
+\fontmapseries ConcreteRoman b > LMSans b
+\fontmapseries ConcreteRoman bx > LMSans bx
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont T1 ConcreteRoman m n 0-5.5 5 eorm5
+\declarefont T1 ConcreteRoman m n 5.5-6.5 6 eorm6
+\declarefont T1 ConcreteRoman m n 6.5-7.5 7 eorm7
+\declarefont T1 ConcreteRoman m n 7.5-8.5 8 eorm8
+\declarefont T1 ConcreteRoman m n 8.5-9.5 9 eorm9
+\declarefont T1 ConcreteRoman m n 9.5-10000 10 eorm10
+% Italic.
+\declarefont T1 ConcreteRoman m it 0-10000 10 eoti10
+% Slanted.
+\declarefont T1 ConcreteRoman m sl 0-5.5 5 eosl5
+\declarefont T1 ConcreteRoman m sl 5.5-6.5 6 eosl6
+\declarefont T1 ConcreteRoman m sl 6.5-7.5 7 eosl7
+\declarefont T1 ConcreteRoman m sl 7.5-8.5 8 eosl8
+\declarefont T1 ConcreteRoman m sl 8.5-9.5 9 eosl9
+\declarefont T1 ConcreteRoman m sl 9.5-10000 10 eosl10
+% Caps and small caps.
+\declarefont T1 ConcreteRoman m sc 0-10000 10 eocc10
+%
+% LH Roman.
+%
+\declarefontfamily LHRoman 1000 1200
+\fontmapfamily LHRoman T1 LMRoman
+\fontmapfamily LHRoman TS1 LMRoman
+% Medium weight.
+% Upright. ser sh [l,u) sz font
+\declarefont T2A LHRoman m n 0-5.5 5 larm0500
+\declarefont T2A LHRoman m n 5.5-6.5 6 larm0600
+\declarefont T2A LHRoman m n 6.5-7.5 7 larm0700
+\declarefont T2A LHRoman m n 7.5-8.5 8 larm0800
+\declarefont T2A LHRoman m n 8.5-9.5 9 larm0900
+\declarefont T2A LHRoman m n 9.5-10.4 10 larm1000
+\declarefont T2A LHRoman m n 10.4-11.4 10.95 larm1095
+\declarefont T2A LHRoman m n 11.4-13.1 12 larm1200
+\declarefont T2A LHRoman m n 13.1-15.6 14.4 larm1440
+\declarefont T2A LHRoman m n 15.6-18.8 17.28 larm1728
+\declarefont T2A LHRoman m n 18.8-22.5 20.74 larm2074
+\declarefont T2A LHRoman m n 22.5-27 24.88 larm2488
+\declarefont T2A LHRoman m n 27-32.5 29.86 larm2986
+\declarefont T2A LHRoman m n 32.5-10000 35.83 larm3583
+% Bold weight. ser sh [l,u) sz font
+\declarefont T2A LHRoman b n 0-5.5 5 larb0500
+\declarefont T2A LHRoman b n 5.5-6.5 6 larb0600
+\declarefont T2A LHRoman b n 6.5-7.5 7 larb0700
+\declarefont T2A LHRoman b n 7.5-8.5 8 larb0800
+\declarefont T2A LHRoman b n 8.5-9.5 9 larb0900
+\declarefont T2A LHRoman b n 9.5-10.4 10 larb1000
+\declarefont T2A LHRoman b n 10.4-11.4 10.95 larb1095
+\declarefont T2A LHRoman b n 11.4-13.1 12 larb1200
+\declarefont T2A LHRoman b n 13.1-15.6 14.4 larb1440
+\declarefont T2A LHRoman b n 15.6-18.8 17.28 larb1728
+\declarefont T2A LHRoman b n 18.8-22.5 20.74 larb2074
+\declarefont T2A LHRoman b n 22.5-27 24.88 larb2488
+\declarefont T2A LHRoman b n 27-32.5 29.86 larb2986
+\declarefont T2A LHRoman b n 32.5-10000 35.83 larb3583
+% Bold extended. ser sh [l,u) sz font
+\declarefont T2A LHRoman bx n 0-5.5 5 labx0500
+\declarefont T2A LHRoman bx n 5.5-6.5 6 labx0600
+\declarefont T2A LHRoman bx n 6.5-7.5 7 labx0700
+\declarefont T2A LHRoman bx n 7.5-8.5 8 labx0800
+\declarefont T2A LHRoman bx n 8.5-9.5 9 labx0900
+\declarefont T2A LHRoman bx n 9.5-10.4 10 labx1000
+\declarefont T2A LHRoman bx n 10.4-11.4 10.95 labx1095
+\declarefont T2A LHRoman bx n 11.4-13.1 12 labx1200
+\declarefont T2A LHRoman bx n 13.1-15.6 14.4 labx1440
+\declarefont T2A LHRoman bx n 15.6-18.8 17.28 labx1728
+\declarefont T2A LHRoman bx n 18.8-22.5 20.74 labx2074
+\declarefont T2A LHRoman bx n 22.5-27 24.88 labx2488
+\declarefont T2A LHRoman bx n 27-32.5 29.86 labx2986
+\declarefont T2A LHRoman bx n 32.5-10000 35.83 labx3583
+%
+% Bera Roman (Bitstream Vera Serif).
+%
+\declarefontfamily BeraRoman 900 1375
+\fontmapshape BeraRoman it > * sl
+\fontmapseries BeraRoman b > * bx
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 BeraRoman m n 0-10000 10 fver8t
+\declarefont T1 BeraRoman m sl 0-10000 10 fvero8t
+% Bold extended.
+\declarefont T1 BeraRoman bx n 0-10000 10 fveb8t
+\declarefont T1 BeraRoman bx sl 0-10000 10 fvebo8t
+%
+% Bera Sans (Bitstream Vera Sans).
+%
+\declarefontfamily BeraSans 900 1375
+\fontmapshape BeraSans it > * sl
+\fontmapseries BeraSans b > * bx
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 BeraSans m n 0-10000 10 fvsr8t
+\declarefont T1 BeraSans m sl 0-10000 10 fvsro8t
+% Bold extended.
+\declarefont T1 BeraSans bx n 0-10000 10 fvsb8t
+\declarefont T1 BeraSans bx sl 0-10000 10 fvsbo8t
+%
+% Bera Mono (Bitstream Vera Mono).
+%
+\declarefontfamily BeraMono 900 1375
+\fontmapshape BeraMono it > * sl
+\fontmapseries BeraMono bx > * b
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 BeraMono m n 0-10000 10 fvmr8t
+\declarefont T1 BeraMono m sl 0-10000 10 fvmro8t
+% Bold weight.
+\declarefont T1 BeraMono b n 0-10000 10 fvmb8t
+\declarefont T1 BeraMono b sl 0-10000 10 fvmbo8t
+%
+% Bitstream Charter.
+%
+\declarefontfamily Charter 1000 1275
+\fontmapseries Charter b > * bx
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 Charter m n 0-10000 10 bchr8t
+\declarefont T1 Charter m it 0-10000 10 bchri8t
+\declarefont T1 Charter m sl 0-10000 10 bchro8t
+\declarefont T1 Charter m sc 0-10000 10 bchrc8t
+% Bold extended.
+\declarefont T1 Charter bx n 0-10000 10 bchb8t
+\declarefont T1 Charter bx it 0-10000 10 bchbi8t
+\declarefont T1 Charter bx sl 0-10000 10 bchbo8t
+\declarefont T1 Charter bx sc 0-10000 10 bchbc8t
+%
+% URW Nimbus Roman (Times) + TeX Gyre Termes.
+%
+\declarefontfamily NimbusRoman 1000 1200
+\fontmapseries NimbusRoman b > * bx
+\fontmapshape NimbusRoman sl > * it % For TS1.
+\fontmapshape NimbusRoman sc > * n % For TS1.
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 NimbusRoman m n 0-10000 10 ptmr8t
+\declarefont TS1 NimbusRoman m n 0-10000 10 ts1-qtmr
+\declarefont T1 NimbusRoman m it 0-10000 10 ptmri8t
+\declarefont TS1 NimbusRoman m it 0-10000 10 ts1-qtmri
+\declarefont T1 NimbusRoman m sl 0-10000 10 ptmro8t
+\declarefont T1 NimbusRoman m sc 0-10000 10 ptmrc8t
+% Bold extended.
+\declarefont T1 NimbusRoman bx n 0-10000 10 ptmb8t
+\declarefont TS1 NimbusRoman bx n 0-10000 10 ts1-qtmb
+\declarefont T1 NimbusRoman bx it 0-10000 10 ptmbi8t
+\declarefont TS1 NimbusRoman bx it 0-10000 10 ts1-qtmbi
+\declarefont T1 NimbusRoman bx sl 0-10000 10 ptmbo8t
+\declarefont T1 NimbusRoman bx sc 0-10000 10 ptmbc8t
+%
+% URW Nimbus Sans (Helvetica).
+%
+\declarefontfamily NimbusSans 950 1250
+\fontmapshape NimbusSans it > * sl
+\fontmapseries NimbusSans b > * bx
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 NimbusSans m n 0-10000 10 phvr8t
+\declarefont T1 NimbusSans m sl 0-10000 10 phvro8t
+\declarefont T1 NimbusSans m sc 0-10000 10 phvrc8t
+% Bold extended.
+\declarefont T1 NimbusSans bx n 0-10000 10 phvb8t
+\declarefont T1 NimbusSans bx sl 0-10000 10 phvbo8t
+\declarefont T1 NimbusSans bx sc 0-10000 10 phvbc8t
+%
+% URW Nimbus Mono (Courier).
+%
+\declarefontfamily NimbusMono 1000 1200
+\fontmapshape NimbusMono it > * sl
+\fontmapseries NimbusMono bx > * b
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 NimbusMono m n 0-10000 10 pcrr8t
+\declarefont T1 NimbusMono m sl 0-10000 10 pcrro8t
+\declarefont T1 NimbusMono m sc 0-10000 10 pcrrc8t
+% Bold weight.
+\declarefont T1 NimbusMono b n 0-10000 10 pcrb8t
+\declarefont T1 NimbusMono b sl 0-10000 10 pcrbo8t
+\declarefont T1 NimbusMono b sc 0-10000 10 pcrbc8t
+%
+% URW Palladio (Palatino) + TeX Gyre Pagella.
+%
+\declarefontfamily URWPalladio 1000 1275
+\fontmapseries URWPalladio b > * bx
+\fontmapshape URWPalladio sl > * it % For TS1.
+\fontmapshape URWPalladio sc > * n % For TS1.
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 URWPalladio m n 0-10000 10 pplr8t
+\declarefont TS1 URWPalladio m n 0-10000 10 ts1-qplr
+\declarefont T1 URWPalladio m it 0-10000 10 pplri8t
+\declarefont TS1 URWPalladio m it 0-10000 10 ts1-qplri
+\declarefont T1 URWPalladio m sl 0-10000 10 pplro8t
+\declarefont T1 URWPalladio m sc 0-10000 10 pplrc8t
+% Bold extended.
+\declarefont T1 URWPalladio bx n 0-10000 10 pplb8t
+\declarefont TS1 URWPalladio bx n 0-10000 10 ts1-qplb
+\declarefont T1 URWPalladio bx it 0-10000 10 pplbi8t
+\declarefont TS1 URWPalladio bx it 0-10000 10 ts1-qplbi
+\declarefont T1 URWPalladio bx sl 0-10000 10 pplbo8t
+\declarefont T1 URWPalladio bx sc 0-10000 10 pplbc8t
+%
+% URW Bookman.
+%
+\declarefontfamily URWBookman 1000 1260
+\fontmapshape URWBookman it > * sl
+\fontmapseries URWBookman bx > * b
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 URWBookman m n 0-10000 10 pbkl8t
+\declarefont T1 URWBookman m sl 0-10000 10 pbklo8t
+\declarefont T1 URWBookman m sc 0-10000 10 pbklc8t
+% Bold weight.
+\declarefont T1 URWBookman b n 0-10000 10 pbkd8t
+\declarefont T1 URWBookman b sl 0-10000 10 pbkdo8t
+\declarefont T1 URWBookman b sc 0-10000 10 pbkdc8t
+%
+% URW Century Schoolbook.
+%
+\declarefontfamily CenturySchoolbook 1000 1300
+\fontmapseries CenturySchoolbook b > * bx
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 CenturySchoolbook m n 0-10000 10 pncr8t
+\declarefont T1 CenturySchoolbook m it 0-10000 10 pncri8t
+\declarefont T1 CenturySchoolbook m sl 0-10000 10 pncro8t
+\declarefont T1 CenturySchoolbook m sc 0-10000 10 pncrc8t
+% Bold extended.
+\declarefont T1 CenturySchoolbook bx n 0-10000 10 pncb8t
+\declarefont T1 CenturySchoolbook bx it 0-10000 10 pncbi8t
+\declarefont T1 CenturySchoolbook bx sl 0-10000 10 pncbo8t
+\declarefont T1 CenturySchoolbook bx sc 0-10000 10 pncbc8t
+%
+% Antykwa Torunska.
+%
+\declarefontfamily AntykwaTorunska 1000 1280
+\fontmapshape AntykwaTorunska sl > * it
+\fontmapseries AntykwaTorunska b > * bx
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 AntykwaTorunska m n 0-10000 10 ec-anttr
+\declarefont T1 AntykwaTorunska m it 0-10000 10 ec-anttri
+\declarefont T1 AntykwaTorunska m sc 0-10000 10 ec-anttrcap
+% Bold extended.
+\declarefont T1 AntykwaTorunska bx n 0-10000 10 ec-anttb
+\declarefont T1 AntykwaTorunska bx it 0-10000 10 ec-anttbi
+\declarefont T1 AntykwaTorunska bx sc 0-10000 10 ec-anttbcap
+%
+% Iwona.
+%
+\declarefontfamily Iwona 1000 1200
+\fontmapshape Iwona it > * sl
+\fontmapseries Iwona bx > * b
+% Light weight. ser sh [l,u) sz font
+\declarefont T1 Iwona l n 0-10000 10 ec-iwonal
+\declarefont T1 Iwona l sl 0-10000 10 ec-iwonali
+\declarefont T1 Iwona l sc 0-10000 10 ec-iwonalcap
+% Light condensed.
+\declarefont T1 Iwona lc n 0-10000 10 ec-iwonacl
+\declarefont T1 Iwona lc sl 0-10000 10 ec-iwonacli
+\declarefont T1 Iwona lc sc 0-10000 10 ec-iwonaclcap
+% Medium weight.
+\declarefont T1 Iwona m n 0-10000 10 ec-iwonar
+\declarefont T1 Iwona m sl 0-10000 10 ec-iwonari
+\declarefont T1 Iwona m sc 0-10000 10 ec-iwonarcap
+% Medium condensed.
+\declarefont T1 Iwona c n 0-10000 10 ec-iwonacr
+\declarefont T1 Iwona c sl 0-10000 10 ec-iwonacri
+\declarefont T1 Iwona c sc 0-10000 10 ec-iwonacrcap
+% Semi-bold weight.
+\declarefont T1 Iwona sb n 0-10000 10 ec-iwonam
+\declarefont T1 Iwona sb sl 0-10000 10 ec-iwonami
+\declarefont T1 Iwona sb sc 0-10000 10 ec-iwonamcap
+% Semi-bold condensed. ser sh [l,u) sz font
+\declarefont T1 Iwona sbc n 0-10000 10 ec-iwonacm
+\declarefont T1 Iwona sbc sl 0-10000 10 ec-iwonacmi
+\declarefont T1 Iwona sbc sc 0-10000 10 ec-iwonacmcap
+% Bold weight.
+\declarefont T1 Iwona b n 0-10000 10 ec-iwonab
+\declarefont T1 Iwona b sl 0-10000 10 ec-iwonabi
+\declarefont T1 Iwona b sc 0-10000 10 ec-iwonabcap
+% Bold condensed.
+\declarefont T1 Iwona bc n 0-10000 10 ec-iwonacb
+\declarefont T1 Iwona bc sl 0-10000 10 ec-iwonacbi
+\declarefont T1 Iwona bc sc 0-10000 10 ec-iwonacbcap
+% Extra bold weight.
+\declarefont T1 Iwona eb n 0-10000 10 ec-iwonah
+\declarefont T1 Iwona eb sl 0-10000 10 ec-iwonahi
+\declarefont T1 Iwona eb sc 0-10000 10 ec-iwonahcap
+% Extra bold condensed.
+\declarefont T1 Iwona ebc n 0-10000 10 ec-iwonach
+\declarefont T1 Iwona ebc sl 0-10000 10 ec-iwonachi
+\declarefont T1 Iwona ebc sc 0-10000 10 ec-iwonachcap
+%
+% URW Gothic (AvantGarde).
+%
+\declarefontfamily URWGothic 900 1450
+\fontmapshape URWGothic it > * sl
+\fontmapseries URWGothic bx > * b
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 URWGothic m n 0-10000 10 pagk8t
+\declarefont T1 URWGothic m sl 0-10000 10 pagko8t
+\declarefont T1 URWGothic m sc 0-10000 10 pagkc8t
+% Bold weight.
+\declarefont T1 URWGothic b n 0-10000 10 pagd8t
+\declarefont T1 URWGothic b sl 0-10000 10 pagdo8t
+\declarefont T1 URWGothic b sc 0-10000 10 pagdc8t
+%
+% URW Chancery.
+%
+\declarefontfamily URWChancery 1150 1150
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 URWChancery m it 0-10000 10 pzcmi8t
+%
+% Eurosym. The T1 encoding we use is just a stub.
+%
+\declarefontfamily Eurosym 1000 1200
+\fontmapshape Eurosym it > * sl
+\fontmapshape Eurosym sc > * n
+\fontmapseries Eurosym bx > * b
+% Medium weight. ser sh [l,u) sz font
+\declarefont T1 Eurosym m n 0-10000 10 feymr10
+\declarefont T1 Eurosym m sl 0-10000 10 feymo10
+% Bold weight.
+\declarefont T1 Eurosym b n 0-10000 10 feybr10
+\declarefont T1 Eurosym b sl 0-10000 10 feybo10
+%
+% Math fonts.
+%
+% Macros to restore some plain TeX math defs, needed by post-hooks of
+% some math font families, e.g., Belleek and EulerMath. `\cm@...'
+% are "action" macros; `\@cm@...' are saved plain TeX defs. We only
+% restore the defs which can be clobbered by the pre-hooks; add new
+% ones as they become needed.
+\def\cm@digits{%
+ \mathcode`0"7030
+ \mathcode`1"7031
+ \mathcode`2"7032
+ \mathcode`3"7033
+ \mathcode`4"7034
+ \mathcode`5"7035
+ \mathcode`6"7036
+ \mathcode`7"7037
+ \mathcode`8"7038
+ \mathcode`9"7039
+}%
+%
+\def\cm@upper@greek{%
+ \let\Gamma\@cm@Gamma
+ \let\Delta\@cm@Delta
+ \let\Theta\@cm@Theta
+ \let\Lambda\@cm@Lambda
+ \let\Xi\@cm@Xi
+ \let\Pi\@cm@Pi
+ \let\Sigma\@cm@Sigma
+ \let\Upsilon\@cm@Upsilon
+ \let\Phi\@cm@Phi
+ \let\Psi\@cm@Psi
+ \let\Omega\@cm@Omega
+}%
+\let\@cm@Gamma\Gamma
+\let\@cm@Delta\Delta
+\let\@cm@Theta\Theta
+\let\@cm@Lambda\Lambda
+\let\@cm@Xi\Xi
+\let\@cm@Pi\Pi
+\let\@cm@Sigma\Sigma
+\let\@cm@Upsilon\Upsilon
+\let\@cm@Phi\Phi
+\let\@cm@Psi\Psi
+\let\@cm@Omega\Omega
+\let\@cm@varsigma\varsigma
+\let\@cm@varrho\varrho
+%
+\def\cm@lower@greek{%
+ \let\varsigma\@cm@varsigma
+ \let\varrho\@cm@varrho
+}%
+\let\@cm@varsigma\varsigma
+\let\@cm@varrho\varrho
+%
+\def\cm@ordinary{%
+ \mathcode`!"5021 % Why the heck is this a closing delimiter?
+ \let\infty\@cm@infty
+ \let\Re\@cm@Re
+ \let\Im\@cm@Im
+}%
+\let\@cm@infty\infty
+\let\@cm@Re\Re
+\let\@cm@Im\Im
+%
+\def\cm@binary{%
+ \mathcode`+="202B
+ \let\triangleleft\@cm@triangleleft
+ \let\triangleright\@cm@triangleright
+}%
+\let\@cm@triangleleft\triangleleft
+\let\@cm@triangleright\triangleright
+%
+\def\cm@relations{%
+ \mathcode`:"303A
+ \mathcode`="303D
+ \let\relbar\@cm@relbar
+ \let\Relbar\@cm@Relbar
+}%
+\let\@cm@relbar\relbar
+\let\@cm@Relbar\Relbar
+%
+\def\cm@delims{%
+ \mathcode`("4028 \delcode`("028300
+ \mathcode`)"5029 \delcode`)"029301
+ \mathcode`["405B \delcode`["05B302
+ \mathcode`]"505D \delcode`]"05D303
+ \delcode`/"02F30E
+}%
+%
+\def\cm@vec{\let\vec\@cm@vec}%
+\let\@cm@vec\vec
+%
+{\catcode`'\active
+\gdef\cm@prime{\let'\@cm@prime}%
+\global\let\@cm@prime'%
+\gdef\def@active@prime{\def'}%
+}%
+%
+\def\cm@fillarrows{%
+ \let\rightarrowfill\@cm@rightarrowfill
+ \let\leftarrowfill\@cm@leftarrowfill
+}%
+\let\@cm@rightarrowfill\rightarrowfill
+\let\@cm@leftarrowfill\leftarrowfill
+%
+% Computer Modern Math.
+%
+\declaremathfontfamily CMMath 1000 1200 OT1 127 48
+\fontmap OT1 CMMath * * > * CMRoman * n
+\fontmapseries CMMath b > * bx
+\fontmap OMX CMMath bx * > * * m *
+% Math letters.
+% Medium weight. ser sh [l,u) sz font
+\declarefont OML CMMath m . 0-5.5 5 cmmi5
+\declarefont OML CMMath m . 5.5-6.5 6 cmmi6
+\declarefont OML CMMath m . 6.5-7.5 7 cmmi7
+\declarefont OML CMMath m . 7.5-8.5 8 cmmi8
+\declarefont OML CMMath m . 8.5-9.5 9 cmmi9
+\declarefont OML CMMath m . 9.5-10.5 10 cmmi10
+\declarefont OML CMMath m . 10.5-10000 12 cmmi12
+%
+% Bold extended.
+\declarefont OML CMMath bx . 0-5.5 5 cmmib5
+\declarefont OML CMMath bx . 5.5-6.5 6 cmmib6
+\declarefont OML CMMath bx . 6.5-7.5 7 cmmib7
+\declarefont OML CMMath bx . 7.5-8.5 8 cmmib8
+\declarefont OML CMMath bx . 8.5-9.5 9 cmmib9
+\declarefont OML CMMath bx . 9.5-10000 10 cmmib10
+%
+% Math symbols.
+% Medium weight. ser sh [l,u) sz font
+\declarefont OMS CMMath m . 0-5.5 5 cmsy5
+\declarefont OMS CMMath m . 5.5-6.5 6 cmsy6
+\declarefont OMS CMMath m . 6.5-7.5 7 cmsy7
+\declarefont OMS CMMath m . 7.5-8.5 8 cmsy8
+\declarefont OMS CMMath m . 8.5-9.5 9 cmsy9
+\declarefont OMS CMMath m . 9.5-10000 10 cmsy10
+% Bold extended.
+\declarefont OMS CMMath bx . 0-5.5 5 cmbsy5
+\declarefont OMS CMMath bx . 5.5-6.5 6 cmbsy6
+\declarefont OMS CMMath bx . 6.5-7.5 7 cmbsy7
+\declarefont OMS CMMath bx . 7.5-8.5 8 cmbsy8
+\declarefont OMS CMMath bx . 8.5-9.5 9 cmbsy9
+\declarefont OMS CMMath bx . 9.5-10000 10 cmbsy10
+%
+% Math operators.
+% Medium weight.
+\declarefont OMX CMMath m . 0-7.5 7 cmex7
+\declarefont OMX CMMath m . 7.5-8.5 8 cmex8
+\declarefont OMX CMMath m . 8.5-9.5 9 cmex9
+\declarefont OMX CMMath m . 9.5-10000 10 cmex10
+%
+% Computer Modern Bright Math.
+%
+\declaremathfontfamily CMBrightMath 1000 1250 OT1 127 48
+\fontmapseries CMBrightMath bx > * m
+\fontmapfamily CMBrightMath OMX CMMath
+% ser sh [l,u) sz font
+\declarefont OT1 CMBrightMath m . 0-8.5 8 cmbr8
+\declarefont OT1 CMBrightMath m . 8.5-9.5 9 cmbr9
+\declarefont OT1 CMBrightMath m . 9.5-14 10 cmbr10
+\declarefont OT1 CMBrightMath m . 14-10000 17 cmbr17
+\declarefont OML CMBrightMath m . 0-8.5 8 cmbrmi8
+\declarefont OML CMBrightMath m . 8.5-9.5 9 cmbrmi9
+\declarefont OML CMBrightMath m . 9.5-10000 10 cmbrmi10
+\declarefont OMS CMBrightMath m . 0-8.5 8 cmbrsy8
+\declarefont OMS CMBrightMath m . 8.5-9.5 9 cmbrsy9
+\declarefont OMS CMBrightMath m . 9.5-10000 10 cmbrsy10
+%
+% Belleek.
+%
+\declaremathfontfamily Belleek 1000 1200 OT1 45 -1
+\fontmapseries Belleek bx > * m
+\mathfontfamilyprehook Belleek {%
+ % Uppercase Greek letters.
+ \mathchardef\Gamma"130
+ \mathchardef\Delta"131
+ \mathchardef\Theta"132
+ \mathchardef\Lambda"133
+ \mathchardef\Xi"134
+ \mathchardef\Pi"135
+ \mathchardef\Sigma"136
+ \mathchardef\Upsilon"137
+ \mathchardef\Phi"138
+ \mathchardef\Psi"139
+ \mathchardef\Omega"17F
+ % Binary operations.
+ \mathchardef\triangleleft"2247
+ \mathchardef\triangleright"2246
+ % Relations.
+ \mathchardef\Relbar"3248
+ % Delimiters.
+ \mathcode`("412E \delcode`(="12E300
+ \mathcode`)"512F \delcode`)="12F301
+ % Accents.
+ \def\vec{\mathaccent"0245 }%
+ % FIXME Other glyphs: mtmi: \tieaccent
+}%
+\mathfontfamilyposthook Belleek {%
+ \cm@upper@greek
+ \cm@binary
+ \cm@relations
+ \cm@delims
+ \cm@vec
+}%
+\declarefont OT1 Belleek m . 0-10000 10 ptmr7t
+\declarefont OT1 Belleek bx . 0-10000 10 ptmb7t
+\declarefont OML Belleek m . 0-10000 10 mtmi
+\declarefont OMS Belleek m . 0-10000 10 mtsy
+\declarefont OMX Belleek m . 0-10000 10 mtex
+%
+% Pazo Math.
+%
+\declaremathfontfamily PazoMath 1000 1275 OT1 127 48
+\fontmapseries PazoMath bx > * b
+\fontmap OMX PazoMath b * > * * m *
+% ser sh [l,u) sz font
+\declarefont OT1 PazoMath m . 0-10000 10 zplmr7t
+\declarefont OT1 PazoMath b . 0-10000 10 zplmb7t
+\declarefont OML PazoMath m . 0-10000 10 zplmr7m
+\declarefont OML PazoMath b . 0-10000 10 zplmb7m
+\declarefont OMS PazoMath m . 0-10000 10 zplmr7y
+\declarefont OMS PazoMath b . 0-10000 10 zplmb7y
+\declarefont OMX PazoMath m . 0-10000 10 zplmr7v
+%
+% PX Fonts Math.
+%
+\declaremathfontfamily PXFontsMath 1000 1275 OT1 127 48
+\fontmapseries PXFontsMath bx > * b
+\declarefont OT1 PXFontsMath m . 0-10000 10 pxr
+\declarefont OT1 PXFontsMath b . 0-10000 10 pxb
+\declarefont OML PXFontsMath m . 0-10000 10 pxmi
+\declarefont OML PXFontsMath b . 0-10000 10 pxbmi
+\declarefont OMS PXFontsMath m . 0-10000 10 pxsy
+\declarefont OMS PXFontsMath b . 0-10000 10 pxbsy
+\declarefont OMX PXFontsMath m . 0-10000 10 pxex
+\declarefont OMX PXFontsMath b . 0-10000 10 pxbex
+%
+% TX Fonts Math.
+%
+\declaremathfontfamily TXFontsMath 1000 1200 OT1 127 48
+\fontmapseries TXFontsMath bx > * b
+\declarefont OT1 TXFontsMath m . 0-10000 10 txr
+\declarefont OT1 TXFontsMath b . 0-10000 10 txb
+\declarefont OML TXFontsMath m . 0-10000 10 txmi
+\declarefont OML TXFontsMath b . 0-10000 10 txbmi
+\declarefont OMS TXFontsMath m . 0-10000 10 txsy
+\declarefont OMS TXFontsMath b . 0-10000 10 txbsy
+\declarefont OMX TXFontsMath m . 0-10000 10 txex
+\declarefont OMX TXFontsMath b . 0-10000 10 txbex
+%
+% Charter Math (from Math Design).
+%
+\declaremathfontfamily CharterMath 1000 1275 OT1 127 48
+
+\fontmapseries CharterMath b > * bx
+\declarefont OT1 CharterMath m . 0-10000 10 mdbchr7t
+\declarefont OT1 CharterMath bx . 0-10000 10 mdbchb7t
+\declarefont OML CharterMath m . 0-10000 10 mdbchri7m
+\declarefont OML CharterMath bx . 0-10000 10 mdbchbi7m
+\declarefont OMS CharterMath m . 0-10000 10 mdbchr7y
+\declarefont OMS CharterMath bx . 0-10000 10 mdbchb7y
+\declarefont OMX CharterMath m . 0-10000 10 mdbchr7v
+\declarefont OMX CharterMath bx . 0-10000 10 mdbchb7v
+%
+% Arev Math.
+%
+% FIXME LaTeX has 127 for \textfont0. What's it for?
+\declaremathfontfamily ArevMath 900 1375 OT1 127 48
+\fontmapseries ArevMath b > * bx
+\fontmapseries ArevMath bx > * m
+\fontmapfamily ArevMath OMX CharterMath
+\declarefont OT1 ArevMath m . 0-10000 10 zavmr7t
+\declarefont OT1 ArevMath bx . 0-10000 10 zavmb7t
+\declarefont OML ArevMath m . 0-10000 10 zavmri7m
+\declarefont OML ArevMath bx . 0-10000 10 zavmbi7m
+\declarefont OMS ArevMath m . 0-10000 10 zavmr7y
+%
+% Iwona Math.
+%
+\declaremathfontfamily IwonaMath 1000 1200 OT1 -1 -1
+\fontmapseries IwonaMath bx > * b
+\declarefont OT1 IwonaMath l . 0-10000 10 rm-iwonal
+\declarefont OT1 IwonaMath lc . 0-10000 10 rm-iwonacl
+\declarefont OT1 IwonaMath m . 0-10000 10 rm-iwonar
+\declarefont OT1 IwonaMath c . 0-10000 10 rm-iwonacr
+\declarefont OT1 IwonaMath sb . 0-10000 10 rm-iwonam
+\declarefont OT1 IwonaMath sbc . 0-10000 10 rm-iwonacm
+\declarefont OT1 IwonaMath b . 0-10000 10 rm-iwonab
+\declarefont OT1 IwonaMath bc . 0-10000 10 rm-iwonacb
+\declarefont OT1 IwonaMath eb . 0-10000 10 rm-iwonah
+\declarefont OT1 IwonaMath ebc . 0-10000 10 rm-iwonach
+% Math letters.
+\declarefont OML IwonaMath l . 0-10000 10 mi-iwonali
+\declarefont OML IwonaMath lc . 0-10000 10 mi-iwonacli
+\declarefont OML IwonaMath m . 0-10000 10 mi-iwonari
+\declarefont OML IwonaMath c . 0-10000 10 mi-iwonacri
+\declarefont OML IwonaMath sb . 0-10000 10 mi-iwonami
+\declarefont OML IwonaMath sbc . 0-10000 10 mi-iwonacmi
+\declarefont OML IwonaMath b . 0-10000 10 mi-iwonabi
+\declarefont OML IwonaMath bc . 0-10000 10 mi-iwonacbi
+\declarefont OML IwonaMath eb . 0-10000 10 mi-iwonahi
+\declarefont OML IwonaMath ebc . 0-10000 10 mi-iwonachi
+% Math symbols.
+\declarefont OMS IwonaMath l . 0-10000 10 sy-iwonalz
+\declarefont OMS IwonaMath lc . 0-10000 10 sy-iwonaclz
+\declarefont OMS IwonaMath m . 0-10000 10 sy-iwonarz
+\declarefont OMS IwonaMath c . 0-10000 10 sy-iwonacrz
+\declarefont OMS IwonaMath sb . 0-10000 10 sy-iwonamz
+\declarefont OMS IwonaMath sbc . 0-10000 10 sy-iwonacmz
+\declarefont OMS IwonaMath b . 0-10000 10 sy-iwonabz
+\declarefont OMS IwonaMath bc . 0-10000 10 sy-iwonacbz
+\declarefont OMS IwonaMath eb . 0-10000 10 sy-iwonahz
+\declarefont OMS IwonaMath ebc . 0-10000 10 sy-iwonachz
+% Math operators.
+\declarefont OMX IwonaMath l . 0-10000 10 ex-iwonal
+\declarefont OMX IwonaMath lc . 0-10000 10 ex-iwonacl
+\declarefont OMX IwonaMath m . 0-10000 10 ex-iwonar
+\declarefont OMX IwonaMath c . 0-10000 10 ex-iwonacr
+\declarefont OMX IwonaMath sb . 0-10000 10 ex-iwonam
+\declarefont OMX IwonaMath sbc . 0-10000 10 ex-iwonacm
+\declarefont OMX IwonaMath b . 0-10000 10 ex-iwonab
+\declarefont OMX IwonaMath bc . 0-10000 10 ex-iwonacb
+\declarefont OMX IwonaMath eb . 0-10000 10 ex-iwonah
+\declarefont OMX IwonaMath ebc . 0-10000 10 ex-iwonach
+%
+% Euler Math.
+%
+\declaremathfontfamily EulerMath 1000 1250 T1 127 176
+\fontmapseries EulerMath bx > * m
+% Text font.
+\declarefont T1 EulerMath m . 0-5.5 5 eorm5
+\declarefont T1 EulerMath m . 5.5-6.5 6 eorm6
+\declarefont T1 EulerMath m . 6.5-7.5 7 eorm7
+\declarefont T1 EulerMath m . 7.5-8.5 8 eorm8
+\declarefont T1 EulerMath m . 8.5-9.5 9 eorm9
+\declarefont T1 EulerMath m . 9.5-10000 10 eorm10
+% Math letters.
+\declarefont OML EulerMath m . 0-6 5 zeurm5
+\declarefont OML EulerMath m . 6-8 7 zeurm7
+\declarefont OML EulerMath m . 8-10000 10 zeurm10
+\declarefont OML EulerMath bx . 0-6 5 zeurb5
+\declarefont OML EulerMath bx . 6-8 7 zeurb7
+\declarefont OML EulerMath bx . 8-10000 10 zeurb10
+% Math symbols.
+\declarefont OMS EulerMath m . 0-6 5 zeusm5
+\declarefont OMS EulerMath m . 6-8 7 zeusm7
+\declarefont OMS EulerMath m . 8-10000 10 zeusm10
+\declarefont OMS EulerMath bx . 0-6 5 zeusb5
+\declarefont OMS EulerMath bx . 6-8 7 zeusb7
+\declarefont OMS EulerMath bx . 8-10000 10 zeusb10
+% Extra math operators.
+\declarefont OMX EulerMath m . 0-10000 10 zeuex10
+% Hooks. Based on gkpmac.tex and eulervm.sty.
+\mathfontfamilyprehook EulerMath {%
+ % Digits.
+ \mathcode`0"7130
+ \mathcode`1"7131
+ \mathcode`2"7132
+ \mathcode`3"7133
+ \mathcode`4"7134
+ \mathcode`5"7135
+ \mathcode`6"7136
+ \mathcode`7"7137
+ \mathcode`8"7138
+ \mathcode`9"7139
+ % Uppercase Greek letters.
+ \mathchardef\Gamma"100
+ \mathchardef\Delta"101
+ \mathchardef\Theta"102
+ \mathchardef\Lambda"103
+ \mathchardef\Xi"104
+ \mathchardef\Pi"105
+ \mathchardef\Sigma"106
+ \mathchardef\Upsilon"107
+ \mathchardef\Phi"108
+ \mathchardef\Psi"109
+ \mathchardef\Omega"10A
+ % Euler doesn't have these.
+ \let\varsigma\sigma
+ \let\varrho\rho
+ % Ordinary.
+ \mathcode`!"02A1
+ \mathchardef\infty"0399
+ \mathchardef\Re"023C
+ \mathchardef\Im"023D
+ % Binary operations.
+ \mathcode`+"22AB
+ % Relations.
+ \mathcode`:"32BA
+ \mathcode`="32BD
+ \mathchardef\bar@minus"181
+ \def\relbar{\mathrel{\smash\bar@minus}}%
+ \mathchardef\Relbar"3182
+ % Delimiters.
+ \mathcode`("42A8 \delcode`("2A8300
+ \mathcode`)"52A9 \delcode`)"2A9301
+ \mathcode`["42DB \delcode`["2DB302
+ \mathcode`]"52DD \delcode`]"2DD303
+ \delcode`/"13D30E
+ % Miscellaneous.
+ \def@active@prime{^\bgroup\mskip2mu\prim@s}%
+ \def\rightarrowfill{$\m@th\bar@minus\mkern-6mu%
+ \cleaders\hbox{$\mkern-2mu\bar@minus\mkern-2mu$}\hfill
+ \mkern-6mu\mathord\rightarrow$}%
+ \def\leftarrowfill{$\m@th\mathord\leftarrow\mkern-6mu%
+ \cleaders\hbox{$\mkern-2mu\bar@minus\mkern-2mu$}\hfill
+ \mkern-6mu\bar@minus$}%
+}%
+%
+\mathfontfamilyposthook EulerMath {%
+ \cm@digits
+ \cm@upper@greek
+ \cm@lower@greek
+ \cm@ordinary
+ \cm@binary
+ \cm@relations
+ \cm@delims
+ \cm@prime
+ \cm@fillarrows
+}%
+%
+% FIXME TeX-Gyre, Kerkis, Fourier-GUTenberg, Antykwa Torunska.
+%
+% Defaults.
+\setfontencoding{OT1}%
+\setfontfamily{CMRoman}%
+\setfontseries{m}%
+\setfontshape{n}%
+\setfontsize{11}%
+% Set some internal parameters for bootstrapping.
+\expandafter\let\expandafter\cur@fenc@list
+ \csname denc@fenc@list/US-ASCII\endcsname
+\fontbasefamily CMRoman % This calls \selectfont.
+%
+\fontfamily roman CMRoman
+\fontfamily sans CMSans
+\fontfamily mono CMMono
+\fontfamily math CMMath
+%
+\documentencoding US-ASCII
+%
+\endinput
diff --git a/contrib/texifont/ftest.tex b/contrib/texifont/ftest.tex
new file mode 100644
index 0000000..566d8fa
--- /dev/null
+++ b/contrib/texifont/ftest.tex
@@ -0,0 +1,445 @@
+\catcode`\@=11
+\input ienc
+\input oenc
+\input fsel
+\catcode`\@=12
+
+\tracingstats1
+\tracingfonts=0 % For this font sampler, too many messages.
+
+\hoffset=-.25in
+\hsize=7in
+\parindent=.5in
+% Avoid any over- and underfull boxes and hyphenation.
+\raggedbottom
+\tolerance=10000
+\hbadness=10000
+\hfuzz=\maxdimen
+\hyphenpenalty=10000
+\rightskip=0pt plus2pc
+
+
+\def\title#1{%
+ \vfil\eject
+ \begingroup
+ \immediate\write16{*** #1}
+ \setfontfamily{CMRoman}
+ \setfontseries{bx}
+ \setfontshape{n}
+ \setfontsize{17}
+ \selectfont
+ \noindent #1\vskip12pt
+ \endgroup
+}
+
+\def\dofamilies{%
+ \begingroup
+ \do{CMRoman}%
+ \do{CMSans}%
+ \do{CMMono}%
+ \setfontencoding{T1}%
+ \do{LMRoman}%
+ \do{LMSans}%
+ \do{LMMono}%
+ \do{CMBright}
+ \do{CMBrightMono}
+ \do{ConcreteRoman}%
+ \do{BeraRoman}%
+ \do{BeraSans}%
+ \do{BeraMono}%
+ \do{Charter}%
+ \do{NimbusRoman}%
+ \do{NimbusSans}%
+ \do{NimbusMono}%
+ \do{URWPalladio}%
+ \do{URWBookman}%
+ \do{CenturySchoolbook}%
+ \do{AntykwaTorunska}%
+ \do{Iwona}%
+ \do{URWGothic}%
+ \setfontshape{it}%
+ \do{URWChancery}%
+ \endgroup
+}
+
+
+%
+% Font switching test.
+%
+\title{Font/base family switching}
+
+\begingroup
+ \def\teststring{%
+ \begingroup
+ \par
+ Default (CMRoman~OT1 medium upright 11pt)~--
+ \setfontseries{b}\selectfont bold~--
+ \bfseries bold extended~--
+ \itshape italic~--
+ \mdseries medium~--
+
+ \setfontsize{14}\selectfont 14\thinspace pt~--
+ \slshape slanted~--
+ \setfontencoding{T1}%
+ \setfontfamily{NimbusRoman}\selectfont NimbusRoman~T1~--
+ \itshape italic~--
+ \setfontfamily{NimbusSans}\selectfont NimbusSans~--
+ \upshape upright~--
+ \bfseries bold extended~--
+ \setfontfamily{NimbusMono}\selectfont NimbusMono~--
+
+ \setfontsize{10}\selectfont 10\thinspace pt~--
+ \itshape italic~--
+ \mdseries medium~--
+ \upshape upright~--
+ \setfontfamily{LMSans}\selectfont LMSans~--
+ \itshape italic~--
+ \setfontfamily{ConcreteRoman}\selectfont ConcreteRoman~--
+ \upshape upright
+ \vskip1pc
+ \endgroup
+ }
+
+ Now the base family is CMRoman:
+ \teststring
+
+ \fontbasefamily NimbusSans
+ Now the base family is NimbusSans:
+ \teststring
+\endgroup
+
+
+%
+% Math test.
+%
+\title{Math}
+
+\begingroup
+ \def\teststring{%
+ $\displaystyle
+ \Longrightarrow
+ 5! - f'(x) + \Re z \times \Im z;\quad
+ \bar u < \tilde e + \vec p - \hat x \cdot \widehat x \ge
+ \widehat{xy} = \widehat{xyz};\allowbreak\quad
+ \gamma, \epsilon, \varepsilon, \sigma, \varsigma, \rho, \varrho,
+ \Gamma, {\it \Gamma};\allowbreak\quad
+ (\exp i),\> [\mathop{\sf sin} \varphi],\>
+ \{\mathop{\tt lim}_{x_1\to\infty} c^{-x_1}\};\allowbreak\quad
+ \biggl(\sum_{i=1}^n a^{b_i}\biggr);\quad
+ \int_{y_2,\ldots,y_n\ge0} x\mskip\thinmuskip dy_2;\quad
+ (| \bigl(\big| \Bigl(\Big| \biggl(\bigg| \Biggl(\Bigg|.
+ $
+ }
+ \def\testfamily#1 #2 #3 #4 {%
+ \par
+ \setfontfamily{#1}\selectfont
+ \fontfamily roman #1
+ \fontfamily sans #2
+ \fontfamily mono #3
+ \fontfamily math #4
+ \hangindent=\parindent \hangafter=1
+ \noindent #4:\quad \teststring\medskip
+ }%
+ \def\test{%
+ \setfontencoding{OT1}%
+ \testfamily CMRoman CMSans CMMono CMMath
+ \setfontencoding{T1}%
+ \testfamily LMRoman LMSans LMMono CMMath
+ \testfamily ConcreteRoman LMSans LMMono EulerMath
+ \testfamily CMBright CMBright CMBrightMono CMBrightMath
+ \testfamily URWPalladio NimbusSans BeraMono PazoMath
+ \testfamily URWPalladio NimbusSans BeraMono PXFontsMath
+ \testfamily NimbusRoman NimbusSans NimbusMono TXFontsMath
+ \testfamily NimbusRoman NimbusSans NimbusMono Belleek
+ \testfamily Charter NimbusSans NimbusMono CharterMath
+ \testfamily BeraSans BeraSans BeraMono ArevMath
+ \testfamily Iwona Iwona LMMono IwonaMath
+ }
+ \test
+ \vskip1pc \hrule \nobreak\vskip1pc
+
+ \bfseries
+ \test
+ \vskip1pc \hrule \nobreak\vskip1pc
+
+ \mdseries\itshape
+ \test
+ \vskip1pc \hrule \nobreak\vskip1pc
+
+ \upshape\setfontsize{17}\selectfont
+ \test
+\endgroup
+
+
+%
+% Test for relative font scaling.
+%
+\title{Relative scaling of font families}
+
+\begingroup
+ \def\do#1{%
+ {\setfontfamily{CMRoman}\setfontencoding{OT1}\selectfont CMRoman}\quad
+ {\setfontfamily{#1}\selectfont #1}\smallskip
+ }
+ \line{\vbox{\hsize=.5\hsize \dofamilies}\qquad
+ \vbox{\hsize=.5\hsize \setfontseries{bx}\dofamilies}}
+\endgroup
+
+%
+% Test for baseline skips.
+%
+\title{Baseline skips}
+
+\begingroup
+ \def\do#1{%
+ \begingroup
+ \setfontfamily{#1}\selectfont
+ (#1).
+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed
+ bibendum nulla id ante. Suspendisse nibh elit, ultricies
+ commodo, ultrices eget, sagittis a, erat. Praesent et
+ augue. Morbi sem. Phasellus augue. Ut bibendum. Sed urna enim,
+ luctus et, gravida vel, malesuada quis, velit. Fusce egestas
+ sapien quis leo.
+ \vskip5pt
+ \endgroup
+ }
+ \dofamilies
+\endgroup
+
+%
+% Showcase for the font families we support.
+%
+\title{Font families showcase}
+
+\def\teststring{What a mess. }
+\def\test#1{%
+ #1%
+ \upshape \teststring
+ \itshape \teststring
+ \slshape \teststring
+ \scshape \teststring
+}
+
+\def\nextfamily#1 {%
+ \vskip2ex\relax
+ \setfontfamily{#1}\setfontsize{11}\setfontseries{m}\setfontshape{n}\selectfont
+ \hrule
+ \nobreak\vskip2ex\relax
+}
+
+\def\nextsize#1 {%
+ \vskip1ex
+ \setfontsize{#1}\setfontseries{m}\setfontshape{n}\selectfont
+ \textindent{\numwithunit{#1}:}%
+ \test\mdseries\par
+ \test{\setfontseries{b}\selectfont}\par
+ \test\bfseries\par
+}%
+\def\numwithunit#1{%
+ \def\num{#1}%
+ \afterassignment\getunit
+ \dimen255=#1pt\relax
+}%
+\def\getunit#1\relax{%
+ \def\temp{#1}%
+ \num \ifx\temp\empty \thinspace [pt]\fi
+}%
+
+
+\nextfamily CMRoman
+CMRoman. The ``bold'' and ``bold extended'' series are missing the
+``caps and small caps'' shape. The ``italic'' and ``slanted'' shapes
+of the ``bold'' series are mapped to the corresponding shapes of the
+``bold extended'' series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily CMSans
+CMSans. For all series, ``italic'' is mapped to ``slanted''. All
+series are missing the ``caps and small caps'' shape. Entire ``bold''
+series is mapped to the ``bold extended'' series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily CMMono
+CMMono. There are no ``bold'' and ``bold extended'' series. All
+series are missing the ``caps and small caps'' shape.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily LMRoman
+LMRoman. Maps to CMRoman for the OT1 encodings, so this is actually
+CMRoman now.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily LMSans
+LMSans. Maps to CMSans for the OT1 encodings, so this is actually
+CMSans now.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily LMMono
+LMMono. Maps to CMMono for the OT1 encodings, so this is actually
+CMMono now.
+\nextsize 10
+\nextsize 1pc
+
+
+\setfontencoding{T1}
+
+\nextfamily LMRoman
+LMRoman T1.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily LMSans
+LMSans T1. The ``bold'' series is mapped to the ``bold extended''
+series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily LMMono
+LMMono T1. The ``bold'' and ``bold extended'' series are missing.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily CMBright
+CMBright T1.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily CMBrightMono
+CMBrightMono T1.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily ConcreteRoman
+ConcreteRoman T1. Only the T1 encoding is currently defined. The
+``bold'' and ``bold extended'' series are mapped to LMSans T1.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily BeraRoman
+BeraRoman. The ``bold'' series maps to the ``bold extended'' series.
+``Slanted'' shapes are artificially slanted. All series are missing
+the ``caps and small caps'' shape.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily BeraSans
+BeraSans. The ``bold'' series is mapped to the ``bold extended''
+series. All series are missing the ``caps and small caps'' shape.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily BeraMono
+BeraMono. The ``bold extended'' series is mapped to the ``bold''
+series. All series are missing the ``caps and small caps'' shape.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily Charter
+Charter. The ``bold'' series is mapped to the ``bold extended''
+series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily NimbusRoman
+NimbusRoman. The ``bold'' series is mapped to the ``bold extended''
+series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily NimbusSans
+NimbusSans. For all series, ``italic'' is mapped to ``slanted''. The
+``bold'' series is mapped to the ``bold extended'' series. In one
+case, this results in double mapping: bx/it maps to b/it which maps
+to b/sl (check out the log file).
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily NimbusMono
+NimbusMono. For all series, ``italic'' is mapped to ``slanted''. The
+``bold extended'' series is mapped to the ``bold'' series. In one
+case, this results in double mapping: bx/it maps to b/it which maps
+to b/sl (check out the log file).
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily URWPalladio
+URWPalladio. The ``bold'' series is mapped to the ``bold extended''
+series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily URWBookman
+URWBookman. The ``bold extended'' series is mapped to the ``bold''
+series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily CenturySchoolbook
+CenturySchoolbook. The ``bold'' series is mapped to the ``bold
+extended'' series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily AntykwaTorunska
+AntykwaTorunska. The ``bold'' series is mapped to the ``bold
+extended'' series. For all series, ``slanted'' is mapped to
+``italic''.
+\nextsize 10
+\nextsize 1pc
+
+
+
+\nextfamily Iwona
+Iwona. The ``bold extended'' series is mapped to the ``bold'' series.
+For all series, ``italic'' is mapped to ``slanted''.
+\nextsize 10
+\nextsize 1pc
+
+\vskip 1pc
+\setfontsize{10pt}\setfontseries{m}\setfontshape{n}\selectfont
+Iwona also supports ``light'', ``semi-bold'' and ``extra-bold''
+series, with ``condensed'' variants:
+
+\def\\#1{\setfontseries{#1}\selectfont\teststring}
+
+\\{l} (light).\par
+\\{lc} (light condensed).
+
+\\{m} (medium).\par
+\\{c} (medium condensed).
+
+\\{sb} (semi-bold).\par
+\\{sbc} (semi-bold condensed).
+
+\\{b} (bold).\par
+\\{bc} (bold condensed).
+
+\\{eb} (extra-bold).\par
+\\{ebc} (extra-bold condensed).
+
+
+
+\nextfamily URWGothic
+URWGothic. The ``bold extended'' series is mapped to the ``bold''
+series.
+\nextsize 10
+\nextsize 1pc
+
+\nextfamily URWChancery
+\itshape
+URWChancery. Only the ``medium italic'' shape is available.
+\nextsize 10
+\nextsize 1pc
+
+\bye
+
+% Local variables:
+% compile-command: "tex --interact=nonstopmode ftest"
+% page-delimiter: "^% \f"
+% End:
diff --git a/contrib/texifont/ienc.tex b/contrib/texifont/ienc.tex
new file mode 100644
index 0000000..275235a
--- /dev/null
+++ b/contrib/texifont/ienc.tex
@@ -0,0 +1,544 @@
+% Some of the macros here (\iCh, \@iCh, \@denc@loop) originated in
+% LaTeX's inputenc.dtx (\DeclareInputText, \DeclareInputMath,
+% \@inpenc@loop). It's not clear whether copyright applies on these
+% small fragments, especially since they have been modified, but just
+% in case, we have permission from the LaTeX Project to distribute
+% them under the GPL.
+%
+% The idea is quite simple -- make all non-ASCII characters active and
+% give them encoding-independent definitions. The font encoding code
+% will map these definitions to relevant font slots based on the
+% current font encoding.
+%
+%
+% \iCh SLOT{TEXT}
+%
+% Define expansion of active character SLOT (*three* arguments as
+% decimal digits) to be TEXT commands. Since in text space matters,
+% we have to guard against TEXT which end in a macro, by checking
+% whether TEXT's \meaning ends in a space. If it does, then we add
+% braces around the definition, in order to avoid any space after the
+% active char being gobbled up once the text is written out to an
+% auxiliary file. FIXME Is this needed?
+\def\iCh#1#2#3#4{%
+ \def\tempa##1 ${}%$ font-lock fix.
+ \def\tempb{#4}%
+ \ifcat_\expandafter\tempa\meaning\tempb$ $_%
+ \@iCh{#1#2#3}{#4}%
+ \else
+ \@iCh{#1#2#3}{{#4}}%
+ \fi
+}%
+%
+% \@iCh{SLOT}{TEXT}
+%
+% Define expansion of active character SLOT to be TEXT commands.
+% To get the active character, we use the fact that \uppercase
+% preserves catcodes of characters: we (temporarily) declare the
+% SLOT char to be the uppercase of ~ (which is active while we're in
+% texinfo.tex) and then "uppercase" it.
+\def\@iCh#1{%
+ \bgroup
+ \uccode`\~#1%
+ \uppercase{%
+ \egroup
+ \def~%
+ }%
+}%
+%
+% \documentencoding ENC
+%
+% Set input encoding to ENC. It first sets all the characters
+% 128-255 to be active (and sets their initial definition to be
+% \@denc@undefined). It then calls the macro which defines the
+% input encoding. Name of the current encoding is stored in
+% \documenttencodingname.
+\def\documentencoding#1 {%
+ % Make sure that the encoding is defined.
+ \expandafter\ifx\csname denc/#1\endcsname \relax
+ \message{^^JWarning: document encoding `#1' is not defined,^^J
+ leaving document encoding unchanged.}%
+ \else
+ % Keyboard characters which don't get a definition will be mapped to
+ % \@denc@undefined.
+ \edef\@denc@undefined{\noexpand\@denc@undefined@{#1}}%
+ % Save encoding name.
+ \edef\documentencodingname{#1}%
+ % Make all potential input characters active.
+ \@denc@loop\^^80\^^ff%
+ % Call the command which will redefine the active characters
+ % according to the document encoding.
+ \csname denc/#1\endcsname
+ % Set up the current font encoding list, which defines priority of
+ % font encodings when searching for a glyph.
+ \expandafter\let\expandafter\cur@fenc@list
+ \csname denc@fenc@list/#1\endcsname
+ % Update encoding list index, for proper glyph caching.
+ \update@enclist@index
+ \fi
+}%
+%
+% Default definition for active characters.
+\def\@denc@undefined@#1{%
+ \errmessage{Keyboard character used is undefined in input encoding `#1'}%
+}%
+%
+% Make characters #1 to #2 inclusive active and undefined.
+\def\@denc@loop#1#2{%
+ \count@`#1\relax
+ \loop
+ \catcode\count@\active
+ \bgroup
+ \uccode`\~\count@
+ \uppercase{%
+ \egroup
+ \let~\@denc@undefined
+ }%
+ \ifnum\count@<`#2\relax
+ \advance\count@\@ne
+ \repeat
+}%
+%
+% \denc@begin{ENC}{FENC-LIST}{DEF-COMMANDS}
+%
+% Define input ("document") encoding ENC and save DEF-COMMANDS which
+% set up the encoding. FENC-LIST defines priorities of font encodings
+% which are searched for glyphs while this document encoding is
+% active.
+\def\denc@define#1#2{%
+ \expandafter\edef\csname denc@fenc@list/#1\endcsname{#2\space}%
+ \expandafter\def\csname denc/#1\endcsname
+}%
+%
+% US-ASCII -- leaves all characters above 127 as undefined.
+\denc@define{US-ASCII}{OT1 OMS OML}{}%
+% End of US-ASCII.
+%
+% Characters common to ISO-8859-1 and ISO-8859-15.
+\def\denc@common@latin@i@xv{%
+\iCh160\tie
+\iCh161\exclamdown
+\iCh162\textcent
+\iCh163\pounds
+\iCh165\textyen
+\iCh167\textsection
+\iCh169\copyright
+\iCh170\ordf
+\iCh171\textguillemotleft
+\iCh172\textlnot % FIXME What about \lnot?
+\iCh173\-%
+\iCh174\registeredsymbol
+\iCh175{\={}}%
+\iCh176\textdegree
+\iCh177\textplusminus
+\iCh178\texttwosuperior
+\iCh179\textthreesuperior
+\iCh181\textmu
+\iCh182\textparagraph
+\iCh183\textperiodcentered
+\iCh185\textonesuperior
+\iCh186\ordm
+\iCh187\textguillemotright
+\iCh191\questiondown
+\iCh192{\`A}%
+\iCh193{\'A}%
+\iCh194{\^A}%
+\iCh195{\~A}%
+\iCh196{\"A}%
+\iCh197{\ringaccent A}%
+\iCh198\AE
+\iCh199{\,C}%
+\iCh200{\`E}%
+\iCh201{\'E}%
+\iCh202{\^E}%
+\iCh203{\"E}%
+\iCh204{\`I}%
+\iCh205{\'I}%
+\iCh206{\^I}%
+\iCh207{\"I}%
+\iCh208\DH
+\iCh209{\~N}%
+\iCh210{\`O}%
+\iCh211{\'O}%
+\iCh212{\^O}%
+\iCh213{\~O}%
+\iCh214{\"O}%
+\iCh215\textmultiply
+\iCh216\O
+\iCh217{\`U}%
+\iCh218{\'U}%
+\iCh219{\^U}%
+\iCh220{\"U}%
+\iCh221{\'Y}%
+\iCh222\TH
+\iCh223\ss
+\iCh224{\`a}%
+\iCh225{\'a}%
+\iCh226{\^a}%
+\iCh227{\~a}%
+\iCh228{\"a}%
+\iCh229{\ringaccent a}%
+\iCh230\ae
+\iCh231{\,c}%
+\iCh232{\`e}%
+\iCh233{\'e}%
+\iCh234{\^e}%
+\iCh235{\"e}%
+\iCh236{\`i}%
+\iCh237{\'i}%
+\iCh238{\^i}%
+\iCh239{\"i}%
+\iCh240\dh
+\iCh241{\~n}%
+\iCh242{\`o}%
+\iCh243{\'o}%
+\iCh244{\^o}%
+\iCh245{\~o}%
+\iCh246{\"o}%
+\iCh247\textdivide
+\iCh248\o
+\iCh249{\`u}%
+\iCh250{\'u}%
+\iCh251{\^u}%
+\iCh252{\"u}%
+\iCh253{\'y}%
+\iCh254\th
+\iCh255{\"y}%
+}% End of characters common to ISO-8859-1 and ISO-8859-15.
+%
+% ISO-8859-1.
+\denc@define{ISO-8859-1}{T1 TS1 OT1 OMS OML}{%
+\denc@common@latin@i@xv
+\iCh164\textcurrency
+\iCh166\textbrokenbar
+\iCh168{\"{}}%
+\iCh180{\'{}}%
+\iCh184{\,{}}% FIXME LaTeX has it as `\c\ ' (`\ ' instead of `{}'), check why (alignment?).
+\iCh188\textonequarter
+\iCh189\textonehalf
+\iCh190\textthreequarters
+}% End of ISO-8859-1.
+%
+% ISO-8859-15.
+\denc@define{ISO-8859-15}{T1 TS1 OT1 OMS OML}{%
+\denc@common@latin@i@xv
+\iCh164\euro
+\iCh166{\v S}%
+\iCh168{\v s}%
+\iCh180{\v Z}%
+\iCh184{\v z}%
+\iCh188\OE
+\iCh189\oe
+\iCh190{\"Y}%
+}% End of ISO-8859-15.
+%
+% ISO-8859-2.
+\denc@define{ISO-8859-2}{T1 TS1 OT1 OMS OML}{%
+\iCh160\tie
+\iCh161{\k A}%
+\iCh162{\u{}}%
+\iCh163{\L}%
+\iCh164\textcurrency
+\iCh165{\v L}%
+\iCh166{\' S}%
+\iCh167\textsection
+\iCh168{\"{}}%
+\iCh169{\v S}%
+\iCh170{\, S}%
+\iCh171{\v T}%
+\iCh172{\'Z}%
+\iCh173\-%
+\iCh174{\v Z}%
+\iCh175{\dotaccent Z}%
+\iCh176\textdegree
+\iCh177{\k a}%
+\iCh178{\k{}}% FIXME LaTeX has it as `\k\ ' (`\ ' instead of `{}'), check why (alignment?).
+\iCh179\l
+\iCh180{\'{}}%
+\iCh181{\v l}%
+\iCh182{\'s}%
+\iCh183{\v{}}%
+\iCh184{\,{}}% FIXME LaTeX has it as `\c\ ' (`\ ' instead of `{}'), check why (alignment?).
+\iCh185{\v s}%
+\iCh186{\, s}%
+\iCh187{\v t}%
+\iCh188{\'z}%
+\iCh189{\H{}}%
+\iCh190{\v z}%
+\iCh191{\dotaccent z}%
+\iCh192{\'R}%
+\iCh193{\'A}%
+\iCh194{\^A}%
+\iCh195{\u A}%
+\iCh196{\"A}%
+\iCh197{\'L}%
+\iCh198{\'C}%
+\iCh199{\,C}%
+\iCh200{\v C}%
+\iCh201{\'E}%
+\iCh202{\k E}%
+\iCh203{\"E}%
+\iCh204{\v E}%
+\iCh205{\'I}%
+\iCh206{\^I}%
+\iCh207{\v D}%
+\iCh208\DJ
+\iCh209{\'N}%
+\iCh210{\v N}%
+\iCh211{\'O}%
+\iCh212{\^O}%
+\iCh213{\H O}%
+\iCh214{\"O}%
+\iCh215\textmultiply
+\iCh216{\v R}%
+\iCh217{\ringaccent U}%
+\iCh218{\'U}%
+\iCh219{\H U}%
+\iCh220{\"U}%
+\iCh221{\'Y}%
+\iCh222{\,T}%
+\iCh223{\ss}%
+\iCh224{\'r}%
+\iCh225{\'a}%
+\iCh226{\^a}%
+\iCh227{\u a}%
+\iCh228{\"a}%
+\iCh229{\'l}%
+\iCh230{\'c}%
+\iCh231{\,c}%
+\iCh232{\v c}%
+\iCh233{\'e}%
+\iCh234{\k e}%
+\iCh235{\"e}%
+\iCh236{\v e}%
+\iCh237{\'i}%
+\iCh238{\^i}%
+\iCh239{\v d}%
+\iCh240\dj
+\iCh241{\'n}%
+\iCh242{\v n}%
+\iCh243{\'o}%
+\iCh244{\^o}%
+\iCh245{\H o}%
+\iCh246{\"o}%
+\iCh247\textdivide
+\iCh248{\v r}%
+\iCh249{\ringaccent u}%
+\iCh250{\'u}%
+\iCh251{\H u}%
+\iCh252{\"u}%
+\iCh253{\'y}%
+\iCh254{\,t}%
+\iCh255{\dotaccent{}}%
+}% End of ISO-8859-2.
+%
+% KOI8-R.
+\denc@define{KOI8-R}{T2A T1 TS1 OT1 OMS OML}{%
+% FIXME \textblacksquare, \surd, \sim, \leq, \geq?
+\iCh149\bullet
+\iCh154\tie
+\iCh156\textdegree
+\iCh157\texttwosuperior
+\iCh158\textperiodcentered
+\iCh159\textdivide
+\iCh163\cyryo
+\iCh179\CYRYO
+\iCh191\copyright
+\iCh192\cyryu
+\iCh193\cyra
+\iCh194\cyrb
+\iCh195\cyrc
+\iCh196\cyrd
+\iCh197\cyre
+\iCh198\cyrf
+\iCh199\cyrg
+\iCh200\cyrh
+\iCh201\cyri
+\iCh202\cyrishrt
+\iCh203\cyrk
+\iCh204\cyrl
+\iCh205\cyrm
+\iCh206\cyrn
+\iCh207\cyro
+\iCh208\cyrp
+\iCh209\cyrya
+\iCh210\cyrr
+\iCh211\cyrs
+\iCh212\cyrt
+\iCh213\cyru
+\iCh214\cyrzh
+\iCh215\cyrv
+\iCh216\cyrsftsn
+\iCh217\cyrery
+\iCh218\cyrz
+\iCh219\cyrsh
+\iCh220\cyrerev
+\iCh221\cyrshch
+\iCh222\cyrch
+\iCh223\cyrhrdsn
+\iCh224\CYRYU
+\iCh225\CYRA
+\iCh226\CYRB
+\iCh227\CYRC
+\iCh228\CYRD
+\iCh229\CYRE
+\iCh230\CYRF
+\iCh231\CYRG
+\iCh232\CYRH
+\iCh233\CYRI
+\iCh234\CYRISHRT
+\iCh235\CYRK
+\iCh236\CYRL
+\iCh237\CYRM
+\iCh238\CYRN
+\iCh239\CYRO
+\iCh240\CYRP
+\iCh241\CYRYA
+\iCh242\CYRR
+\iCh243\CYRS
+\iCh244\CYRT
+\iCh245\CYRU
+\iCh246\CYRZH
+\iCh247\CYRV
+\iCh248\CYRSFTSN
+\iCh249\CYRERY
+\iCh250\CYRZ
+\iCh251\CYRSH
+\iCh252\CYREREV
+\iCh253\CYRSHCH
+\iCh254\CYRCH
+\iCh255\CYRHRDSN
+}% End of KOI8-R.
+%
+% CP1251.
+\denc@define{CP1251}{T2A T1 TS1 OT1 OMS OML}{%
+\iCh128\CYRDJE
+\iCh129{\'\CYRG}%
+\iCh130\textquotesinglbase
+\iCh131{\'\cyrg}%
+\iCh132\textquotedblbase
+\iCh133\dots
+\iCh134\textdagger
+\iCh135\textdaggerdbl
+\iCh136\euro
+\iCh137\textperthousand
+\iCh138\CYRLJE
+\iCh139\textguilsinglleft
+\iCh140\CYRNJE
+\iCh141{\'\CYRK}%
+\iCh142\CYRTSHE
+\iCh143\CYRDZHE
+\iCh144\cyrdje
+\iCh145\textquoteleft
+\iCh146\textquoteright
+\iCh147\textquotedblleft
+\iCh148\textquotedblright
+\iCh149\bullet
+\iCh150\textendash
+\iCh151\textemdash
+\iCh153\texttrademark
+\iCh154\cyrlje
+\iCh155\textguilsinglright
+\iCh156\cyrnje
+\iCh157{\'\cyrk}%
+\iCh158\cyrtshe
+\iCh159\cyrdzhe
+\iCh160\tie
+\iCh161\CYRUSHRT
+\iCh162\cyrushrt
+\iCh163\CYRJE
+\iCh164\textcurrency
+\iCh165\CYRGUP
+\iCh166\textbrokenbar
+\iCh167\textsection
+\iCh168\CYRYO
+\iCh169\copyright
+\iCh170\CYRIE
+\iCh171\textguillemotleft
+\iCh172\textlnot
+\iCh173\-%
+\iCh174\registeredsymbol
+\iCh175\CYRYI
+\iCh176\textdegree
+\iCh177\textplusminus
+\iCh178\CYRII
+\iCh179\cyrii
+\iCh180\cyrgup
+\iCh181\textmu
+\iCh182\textparagraph
+\iCh183\textperiodcentered
+\iCh184\cyryo
+\iCh185\textnumero
+\iCh186\cyrie
+\iCh187\textguillemotright
+\iCh188\cyrje
+\iCh189\CYRDZE
+\iCh190\cyrdze
+\iCh191\cyryi
+\iCh192\CYRA
+\iCh193\CYRB
+\iCh194\CYRV
+\iCh195\CYRG
+\iCh196\CYRD
+\iCh197\CYRE
+\iCh198\CYRZH
+\iCh199\CYRZ
+\iCh200\CYRI
+\iCh201\CYRISHRT
+\iCh202\CYRK
+\iCh203\CYRL
+\iCh204\CYRM
+\iCh205\CYRN
+\iCh206\CYRO
+\iCh207\CYRP
+\iCh208\CYRR
+\iCh209\CYRS
+\iCh210\CYRT
+\iCh211\CYRU
+\iCh212\CYRF
+\iCh213\CYRH
+\iCh214\CYRC
+\iCh215\CYRCH
+\iCh216\CYRSH
+\iCh217\CYRSHCH
+\iCh218\CYRHRDSN
+\iCh219\CYRERY
+\iCh220\CYRSFTSN
+\iCh221\CYREREV
+\iCh222\CYRYU
+\iCh223\CYRYA
+\iCh224\cyra
+\iCh225\cyrb
+\iCh226\cyrv
+\iCh227\cyrg
+\iCh228\cyrd
+\iCh229\cyre
+\iCh230\cyrzh
+\iCh231\cyrz
+\iCh232\cyri
+\iCh233\cyrishrt
+\iCh234\cyrk
+\iCh235\cyrl
+\iCh236\cyrm
+\iCh237\cyrn
+\iCh238\cyro
+\iCh239\cyrp
+\iCh240\cyrr
+\iCh241\cyrs
+\iCh242\cyrt
+\iCh243\cyru
+\iCh244\cyrf
+\iCh245\cyrh
+\iCh246\cyrc
+\iCh247\cyrch
+\iCh248\cyrsh
+\iCh249\cyrshch
+\iCh250\cyrhrdsn
+\iCh251\cyrery
+\iCh252\cyrsftsn
+\iCh253\cyrerev
+\iCh254\cyryu
+\iCh255\cyrya
+}% End of CP1251.
+%
+\endinput
diff --git a/contrib/texifont/oenc.tex b/contrib/texifont/oenc.tex
new file mode 100644
index 0000000..2caa27c
--- /dev/null
+++ b/contrib/texifont/oenc.tex
@@ -0,0 +1,990 @@
+%
+% Intro
+% =====
+%
+% A glyph can be accessed with one of the three different kinds of
+% macros:
+%
+% command a macro without arguments, e.g., |\textdegree|;
+%
+% composite a macro taking one argument, producing a single glyph
+% from a font;
+%
+% accent a macro taking one argument, producing a glyph (the
+% argument) with another glyph (accent) superimposed.
+%
+% Accents can place an accent mark on any glyph, but typographically
+% this often doesn't look good. Therefore some fonts provide some
+% accented glyphs designed by a designer ("composites"). For example,
+% typing |\'a| will result in the acute accent (|\'|) being placed
+% over the glyph |a| in some encodings (e.g., in OT1), but will
+% produce a single glyph (|a| with acute) in others (e.g., T1).
+%
+% Note that a font may contain both composites (for some letters) and
+% accent marks. When a composite is not available in the font, the
+% accent can be used to typeset the desired glyph.
+%
+% Besides the visual advantages, composites are preferable for a
+% technical reason -- TeX does not hyphenate words which contain
+% accents.
+%
+% Glyph searching
+% ===============
+%
+% Glyph searching means identifying a font encoding which both
+% contains the glyph and is supported by the current font family.
+%
+% The simplest approach at glyph searching is to search through the
+% list of encodings in which the glyph exists to find the first one
+% supported by the current font family.
+%
+% This however can result in using unnecessarily large number of
+% fonts. In order to decrease the font usage we can provide hints to
+% the glyph searching mechanism as to which font encodings are the
+% most likely to contain glyphs under different circumstances.
+%
+% There is some relation between input encodings and font encodings,
+% although it is not necessarily a one-to-one (or a many-to-one)
+% mapping. Each input encoding defines a list of font encodings which
+% should be tried first (we call it "the current font encoding list",
+% |\cur@fenc@list|). These are encodings which cover the input
+% encoding completely. Only if we don't find an encoding in this list
+% which is both supported by the current font family and contains the
+% glyph, we start searching the glyph's encoding list.
+%
+% Searching for a glyph involves an ambiguity -- the same glyph be
+% typeset as either an accent over a letter, or as a single composite
+% glyph. Ideally a composite is preferable, but if an accent is
+% available without changing the current font, we might prefer the
+% accent.
+%
+% This is how we do the searching:
+%
+% 1) Check the current encoding + current font encoding list (set up
+% by |@documentencoding|) "breadth-first", i.e., preferring accents
+% in an earlier encoding over composites in later encodings. This
+% is to hopefully minimize the font usage, as we would find "the
+% earliest" usable font.
+%
+% 2) If the glyph was not found in step 1, search the glyph's encoding
+% list. We now prefer composites -- we'll consider an accent only
+% when none of the composite's encodings is supported by the
+% current font family. We now don't care about font usage and
+% search "the best" glyph, as this is a (supposedly rare) situation
+% when a "non-standard" font will get used anyway, e.g., when a
+% user requests a Cyrillic glyph while inside a Latin environment.
+%
+% Cache
+% =====
+%
+% After we've found the glyph we can cache it, i.e., arrange for the
+% the glyph's macro the next time to typeset the glyph without doing
+% the searching again.
+%
+% Such cache however must be aware of changes in settings which affect
+% glyph searching, which are:
+%
+% 1) the current font encoding (E);
+% 2) the current font encoding list, set up by |@documentencoding| (EL);
+% 3) font encoding list of the current font family (FEL).
+%
+% Therefore, the first thing we do is assign a unique index to every
+% combination of E+EL+FEL we encounter in the document. Whenever we
+% change E, EL or FEL we check if the new combination have already
+% been assigned an index; if not, we allocate next index for the new
+% combination (see |\update@enclist@index|). When we cache a glyph we
+% use this index to remember for which combination of E+EL+FEL this
+% cache entry is for.
+%
+% This is how glyph caching works. Let's say we have to typeset
+% |\'a|. |\'| (being a composite or an accent) calls a macro named
+% |\N\'-a| (single command sequence, N is the index of the current
+% E+EL+FEL combination) if it's defined; if it's not defined, |\'|
+% calls glyph searching macro. After the glyph searching macro finds
+% the glyph corresponding to |\'a|, it defines the macro named
+% |\N\'-a| to typeset that glyph (using either accent or composite,
+% whatever was found), so the next time we encounter |\'a| we won't
+% search for the glyph (unless the E+EL+FEL combination has changed
+% and |\'a| had not yet been cached for that combo).
+%
+% The drawback of this method is that TeX's memory gets filled with
+% many cache entries for every E+EL+FEL combo ever used in the
+% document. It's possible to construct the glyph cache in a way to
+% avoid this -- for example, to define only one cache macro for |\'a|,
+% and add to it a new branch for each new E+EL+FEL combination, but
+% naturally this will be slower.
+%
+% Internal macros ("variables")
+% =============================
+%
+% fenc@enc font encoding currently being defined.
+%
+% fenc@list/NAME list of encodings for the glyph NAME.
+%
+% cur@fenc@list "the current font encoding list" (see "Glyph
+% searching" above).
+%
+% ENC/NAME definition of glyph NAME in encoding ENC.
+%
+% @enc encoding of the glyph (set after finding the
+% glyph / retrieving the glyph from the cache).
+%
+% cache@enc@ENC macro that defines \@enc to be ENC.
+%
+% N\NAME cache entry for glyph \NAME under a combination of
+% E+EL+FEL number N.
+%
+%
+%
+% \fCmd{COMMAND}{TEXT}
+%
+% Define a command that does not take arguments. Call \f@restore@enc
+% inside TEXT if you need to restore the original encoding (remember,
+% before the command is called, the encoding is changed to the one for
+% which the command was defined, which can be different from the
+% current user's encoding).
+\def\fCmd#1#2{%
+ \def#1{\f@search@command #1}%
+ \f@def@enc@glyph#1%
+ {\f@change@enc #2\f@enc@egroup}%
+}%
+%
+% \fSym{COMMAND}{SLOT}
+%
+% Define a font glyph in SLOT.
+\def\fSym#1#2{\fCmd{#1}{\char#2 }}%
+%
+% \fCmdd{COMMAND}{TEXT}
+%
+% Define a command that takes one argument. Call \f@restore@enc
+% inside TEXT before typesetting the argument, to restore the original
+% encoding (remember, before the command is called, the encoding is
+% changed to the one for which the command was defined, which can be
+% different from the current user's encoding).
+\def\fCmdd#1#2{%
+ \def#1{\f@search@accent #1}% When searching, treat it as an accent.
+ \f@def@enc@glyph#1%
+ ##1{\f@change@enc #2\f@enc@egroup}%
+}%
+%
+% \fCmp{COMMAND}{ARG}{TEXT}
+%
+% Define a composite command. If there's a corresponding accent,
+% composite will override the accent when the argument is ARG.
+\def\fCmp#1#2#3{%
+ \def#1{\f@search@composite #1}%
+ \f@def@enc@glyph{#1-\string#2}%
+ {\f@change@enc #3\f@enc@egroup}%
+}%
+%
+% \fCmpSym{COMMAND}{ARG}{SLOT}
+%
+% Same as \fCmp, but define a composite glyph in SLOT.
+\def\fCmpSym#1#2#3{\fCmp#1#2{\char#3}}%
+%
+% \fAcc{COMMAND}{SLOT}
+%
+% Define an accent in SLOT. If there are corresponding composite
+% commands for some arguments, they will override the accent for those
+% arguments.
+\def\fAcc#1#2{%
+ \def#1{\f@search@accent #1}%
+ \f@def@enc@glyph#1%
+ {\f@do@accent{#2}}%
+}%
+%
+%
+%
+% \f@def@enc@glyph{NAME}{DEF}
+%
+% Define a glyph in the current encoding.
+\def\f@def@enc@glyph#1{%
+ % Add the font encoding to the encoding list for the command.
+ \expandafter\def\expandafter\temp\expandafter{%
+ \csname fenc@list/\string#1\endcsname
+ }%
+ \expandafter\ifx\temp\relax
+ \let\tempa\empty
+ \else
+ \edef\tempa{\temp}%
+ \fi
+ \expandafter\edef\temp{\fenc@enc\space\tempa}%
+ % Start definition of the glyph command for the current encoding.
+ \expandafter\def \csname\fenc@enc/\string#1\endcsname
+}%
+%
+% \f@change@enc
+%
+% Start a group with \f@enc@bgroup and change font encoding to \@enc,
+% if the current encoding is different. The original encoding is
+% saved, call \f@restore@enc inside the command's def to restore it.
+\def\f@change@enc{%
+ \f@enc@bgroup
+ % Save original encoding -- the glyph macro might need to restore
+ % it, e.g., to typeset its argument.
+ \let\f@orig@enc\f@encoding
+ % Switch encoding, if needed. \@enc is set when the glyph is
+ % found or retrieved from the cache.
+ \ifx\f@encoding\@enc \else
+ \setfontencoding{\@enc}\selectfont
+ \fi
+}%
+%
+% \f@restore@enc
+%
+% Restore encoding saved by \f@change@enc.
+\def\f@restore@enc{%
+ \ifx\f@orig@enc\f@encoding \else
+ \setfontencoding{\f@orig@enc}\selectfont
+ \fi
+}%
+%
+% These are used by glyphs to start and end a group isolating a font
+% encoding change. Accents turn these off to avoid any grouping
+% inside their argument, because grouping breaks accents.
+\let\f@enc@bgroup\bgroup
+\let\f@enc@egroup\egroup
+%
+% \f@do@accent{SLOT}{ARG}
+%
+% Typeset an accent in SLOT over the ARG.
+\def\f@do@accent#1#2{%
+ \bgroup
+ % Avoid starting any more groups -- they're not needed because we
+ % already have one, and a group between the accent and the
+ % accented letter will break the accent.
+ \let\f@enc@bgroup\empty
+ \let\f@enc@egroup\empty
+ % Preload any fonts in advance, to prevent grouping (possible when
+ % loading fonts) from messing with the accent. Also save the
+ % space factor of the argument -- we'll need to restore it,
+ % otherwise, e.g., \'A will have the factor of 1000 instead of 999.
+ \setbox\z@\hbox{#2%
+ \xdef\f@do@accent@spacefactor{\spacefactor\the\spacefactor}}%
+ % Save the current font encoding and switch it.
+ \f@change@enc
+ % Start the accent.
+ \accent#1
+ % Turn off \fontnotify and \setleading, because their \message and
+ % \setbox will break the accent. We don't turn off \fontwarn
+ % because a warning would mean that the fonts are broken anyway,
+ % and a warning might help diagnosing.
+ \let\@fontnotify\gobble
+ \let\@setleading\gobble
+ % Restore the original encoding.
+ \f@restore@enc
+ % Typeset the argument.
+ #2\f@do@accent@spacefactor % Restore the space factor.
+ \egroup
+}%
+%
+%
+%
+% \f@search@command{COMMAND}
+%
+% Search for the glyph COMMAND and typeset it.
+\def\f@search@command#1{%
+ % Check the cache of the current font encoding list.
+ \expandafter\let \expandafter\temp
+ \csname \the\enclist@curr\string#1\endcsname
+ %
+ \ifx\temp\relax
+ % The glyph is not in the cache, search.
+ %\message{^^J Glyph command `\string#1' is not
+ % in the cache (idx \the\enclist@curr).}%
+ \def\f@search@cmd{\string#1}%
+ \let\f@search@arg\empty
+ \let\f@accent@arg\empty
+ \f@search@encodings
+ \else
+ % The glyph is in the cache.
+ %\message{^^J Glyph command `\string#1' is
+ % in the cache (idx \the\enclist@curr).}%
+ \temp
+ \fi
+}%
+%
+% \f@search@composite{COMMAND}{ARGUMENT}
+%
+% Search for the composite COMMAND + ARGUMENT and typeset it. If such
+% composite is not defined but an accent named COMMAND is, the accent
+% will be substituted.
+\def\f@search@composite#1#2{%
+ % Check the cache with the current font encoding list. \empty after
+ % #2 is for a situation like \'{} (empty ARGUMENT).
+ \expandafter\let \expandafter\temp
+ \csname \the\enclist@curr\string#1-\string#2\empty\endcsname
+ %
+ \ifx\temp\relax
+ % The glyph is not in the cache, search.
+ %\message{^^J Glyph composite `\string#1{\string#2\empty}' is not
+ % in the cache (idx \the\enclist@curr).}%
+ \def\f@search@arg{-\string#2\empty}%
+ \def\f@search@cmd{\string#1}%
+ \def\f@accent@arg{{#2}}%
+ \f@search@encodings
+ \else
+ % The glyph is in the cache.
+ %\message{^^J Glyph composite `\string#1{\string#2\empty}' is
+ % in the cache (idx \the\enclist@curr).}%
+ \temp
+ \fi
+}%
+%
+% \f@search@accent{COMMAND}{ARGUMENT}
+%
+% Search for the accent COMMAND and typeset it over the ARGUMENT. If a
+% composite with the name COMMAND is defined with the ARGUMENT, it
+% might be used in preference to the accent.
+\let\f@search@accent\f@search@composite
+%
+%
+%
+% \f@search@encodings
+%
+% Search for a glyph (accent/composite/command), first in the current
+% encoding, then in the current font encoding list (set up by
+% @documentencoding), then in all encodings in which the glyph
+% appears. After the glyph is found, define the cache entry for the
+% glyph and typeset the glyph.
+\def\f@search@encodings{%
+ \let\@enc\relax
+ \let\f@cache@arg\f@search@arg
+ % Check the current font encoding + the current font encoding list
+ % breadth-first. We want to find a glyph as early in the list as
+ % possible (to hopefully minimize number of fonts that get loaded),
+ % therefore we prefer an accent in an earlier encoding over a
+ % composite in a later encoding, hence the "breadth first" search.
+ \edef\temp{\f@encoding\space\cur@fenc@list}%
+ \f@search@breadthfirst \temp
+ %
+ \ifx\@enc\relax
+ % Nothing found, so we try a different tactic. We check encoding
+ % list of the glyph to find the first encoding which is supported
+ % by the current font family. One complication is that a glyph
+ % can appear as a command, a composite or an accent, so we need to
+ % check all possibilities (but preferring composites over
+ % accents).
+ %
+ % Check the composite. If \f@search@arg is \empty, this will check
+ % encoding list of the command, which is exactly what we need.
+ \expandafter\f@search@glyph
+ \csname fenc@list/\f@search@cmd\f@search@arg\endcsname
+ %
+ \ifx\@enc\relax
+ % Nothing found, check the font encoding list of the command / accent.
+ \let\f@search@arg\empty % It's not a composite, so we don't need arg part.
+ \expandafter\f@search@glyph
+ \csname fenc@list/\f@search@cmd\endcsname
+ %
+ \ifx\@enc\relax
+ % Still nothing found, which means the current family does not
+ % support any of the composite's / command's / accent's encodings.
+ \errmessage{^^JThe font family \f@family\space does not support
+ the command `\f@search@cmd\f@cache@arg'}%
+ \fi
+ \else
+ % We've found a composite (or a command), so we don't need the arg below.
+ \let\f@accent@arg\empty
+ \fi
+ \fi
+ % Make the cache entry.
+ \edef\temp##1{%
+ \expandafter\gdef\expandafter\noexpand
+ \csname \the\enclist@curr\f@search@cmd\f@cache@arg\endcsname{%
+ % Set \@enc to the encoding of the glyph.
+ \expandafter\noexpand
+ \csname cache@enc@\@enc\endcsname
+ % Call the glyph's definition for the encoding we've found.
+ \expandafter\noexpand
+ \csname\@enc/\f@search@cmd\f@search@arg\endcsname ##1%
+ }%
+ }%
+ \expandafter\temp\expandafter{\f@accent@arg}%
+ % Typeset the glyph.
+ \csname \the\enclist@curr\f@search@cmd\f@cache@arg\endcsname
+}%
+%
+% \f@search@breadthfirst \ENC-LIST
+%
+% Search (recursively) for a glyph in encodings from \ENC-LIST,
+% preferring an accent in an earlier encoding over a composite in a
+% later encoding. When the glyph is found, \@enc, \f@search@arg and
+% \f@accent@arg are set accordingly (see \f@search@encodings).
+\def\f@search@breadthfirst#1{%
+ \let\next\@f@search@breadthfirst % \@f@search@breadthfirst needs this.
+ \expandafter\@f@search@breadthfirst #1\finish
+}%
+%
+\def\@f@search@breadthfirst#1 #2\finish{%
+ % See if this is the last encoding in the list.
+ \def\temp{#2}%
+ \ifx\temp\empty % Yes, gobble the list's sentinel.
+ \let\next\gobble@to@finish
+ \fi
+ % See if this encoding is supported by the current family.
+ \expandafter\ifx \csname fam@enc/\f@family/#1\endcsname \relax
+ \else
+ % See if the encoding contains the composite (or the command, when
+ % \f@search@arg is \empty).
+ \expandafter\ifx \csname #1/\f@search@cmd\f@search@arg\endcsname \relax
+ % No, but maybe the encoding contains the accent. (This might
+ % also check the second time for the command if it was not found
+ % above.)
+ \expandafter\ifx \csname #1/\f@search@cmd\endcsname \relax \else
+ \let\f@search@arg\empty % \f@search@encodings needs this.
+ \def\@enc{#1}%
+ \let\next\gobble@to@finish % Gobble the rest of the list.
+ \fi
+ \else % Yes, this encoding contains the composite (or a command).
+ \let\f@accent@arg\empty % \f@search@encodings needs this.
+ \def\@enc{#1}%
+ \let\next\gobble@to@finish % Gobble the rest of the list.
+ \fi
+ \fi
+ %
+ \next#2\finish
+}%
+%
+% \f@search@glyph \ENC-LIST
+%
+% Search (recursively) for a particular type of glyph
+% (command/composite/accent, determined by the combination of
+% \f@search@cmd and \f@search@arg) in encodings from \ENC-LIST.
+\def\f@search@glyph#1{%
+ \ifx#1\relax \else
+ \let\next\@f@search@glyph % \@f@search@glyph needs this.
+ \expandafter\@f@search@glyph#1\finish
+ \fi
+}%
+%
+\def\@f@search@glyph#1 #2\finish{%
+ % See if this is the last encoding in the list.
+ \def\temp{#2}%
+ \ifx\temp\empty % Yes, gobble the list's sentinel.
+ \let\next\gobble@to@finish
+ \fi
+ % See if this encoding is supported by the current family.
+ \expandafter\ifx \csname fam@enc/\f@family/#1\endcsname \relax
+ \else % Yes, see if the encoding contains the glyph.
+ \expandafter\ifx \csname #1/\f@search@cmd\f@search@arg\endcsname \relax
+ \else
+ \def\@enc{#1}%
+ \let\next\gobble@to@finish % Gobble the rest of the list.
+ \fi
+ \fi
+ %
+ \next#2\finish
+}%
+%
+%
+%
+% Font ("output") encodings. LaTeX's ltoutenc.dtx v1.99h has been
+% used as reference.
+%
+% Some commands common to several encodings.
+%
+\def\registeredsymbol{\leavevmode\raise.7ex\hbox{\textregistered}}
+\def\@euro{{\setfontfamily{Eurosym}\setfontencoding{T1}\selectfont\char101}}%
+\def\aa{\ringaccent a}%
+\def\AA{\ringaccent A}%
+\def\@cedilla#1#2{{\setbox\z@\hbox{\f@restore@enc #2}%
+ \ifdim\ht\z@=1ex\accent#1 \f@restore@enc #2%
+ \else\ooalign{\unhbox\z@\crcr\hidewidth\char#1\hidewidth}\fi}}%
+\def\@udotaccent#1{{\o@lign{\relax\f@restore@enc#1\crcr
+ \hidewidth\sh@ft{-1ex}.\hidewidth}}}%
+\def\@ubaraccent#1#2{{\o@lign{\relax\f@restore@enc#2\crcr
+ \hidewidth\sh@ft{-3ex}\vbox to.2ex{\hbox{\char#1}\vss}\hidewidth}}}%
+%
+% This defines encoding used when defining font glyph and commands.
+\def\fenc@begin#1{%
+ \def\fenc@enc{#1}%
+ \expandafter\def\csname cache@enc@#1\endcsname{\def\@enc{#1}}%
+}%
+%
+% OT1.
+\fenc@begin{OT1}
+\fSym\ptexi{16}
+\fSym\j{17}
+\fAcc\`{18}
+\fCmp\`i{\f@restore@enc\`\ptexi}
+\fAcc\'{19}
+\fCmp\'i{\f@restore@enc\'\ptexi}
+\fAcc\v{20}
+\fAcc\u{21}
+\fAcc\={22}
+\fAcc\ringaccent{23}
+\fCmp\ringaccent A{\leavevmode\setbox0\hbox{!}\dimen@\ht0\advance\dimen@-1ex%
+ \rlap{\raise.67\dimen@\hbox{\char'27}}A}
+\fSym\ss{25}
+\fSym\ae{26}
+\fSym\oe{27}
+\fSym\o{28}
+\fSym\AE{29}
+\fSym\OE{30}
+\fSym\O{31}
+\fCmd\l{\char32l}
+\fCmd\L{\leavevmode\setbox0\hbox{L}\hbox to\wd0{\hss\char32L}}
+\fCmd\textquotedblright{`\"}
+\fCmd\textdollar{{\ifdim\fontdimen\@ne\font>\z@\slshape\else\upshape\fi\$}}
+\fCmd\textquoteright{`\'}
+\fCmd\exclamdown{!`}
+\fCmd\questiondown{?`}
+\fSym\textquotedblleft{92}
+\fAcc\^{94}
+\fCmp\^i{\f@restore@enc\^\ptexi}
+\fAcc\dotaccent{95}
+\fCmpSym\dotaccent i{`\i}
+\fCmpSym\dotaccent\i{`\i}
+\fCmd\textquoteleft{`\`}
+\fSym\textendash{123}
+\fSym\textemdash{124}
+\fAcc\H{125}
+\fAcc\~{126}
+\fAcc\"{127}
+\fCmp\"i{\f@restore@enc\"\ptexi}
+\fCmd\pounds{{\ifdim\fontdimen\@ne\font>\z@\itshape\else
+ \setfontshape{ui}\selectfont\fi\$}}
+\fCmd\euro\@euro
+\fCmdd\,{\@cedilla{24}{#1}}
+\fCmdd\udotaccent{\@udotaccent{#1}}
+\fCmdd\ubaraccent{\@ubaraccent{22}{#1}}
+\fCmd\ordf{\leavevmode\raise1ex\hbox{\scalefont{727}\underbar{a}}}
+\fCmd\ordm{\leavevmode\raise1ex\hbox{\scalefont{727}\underbar{o}}}
+\fCmd\ij{\nobreak\hskip\z@skip i\kern-0.02em j\nobreak\hskip\z@skip}
+\fCmd\IJ{\nobreak\hskip\z@skip I\kern-0.02em J\nobreak\hskip\z@skip}
+\fCmd\textonesuperior{$^{\hbox{\scalefont{727}1}}$}
+\fCmd\texttwosuperior{$^{\hbox{\scalefont{727}2}}$}
+\fCmd\textthreesuperior{$^{\hbox{\scalefont{727}3}}$}
+\fCmd\textonequarter{$\hbox{\scalefont{727}1}\over\hbox{\scalefont{727}4}$}
+\fCmd\textonehalf{$\hbox{\scalefont{727}1}\over\hbox{\scalefont{727}2}$}
+\fCmd\textthreequarters{$\hbox{\scalefont{727}3}\over\hbox{\scalefont{727}4}$}
+% End of OT1.
+%
+% OML.
+\fenc@begin{OML}
+\fSym\textless{`\<}
+\fSym\textgreater{`\>}
+%\fSym\star{63}% FIXME this requires redefining \point.
+\fAcc\tieaccent{127}
+% End of OML.
+%
+% OMS.
+\fenc@begin{OMS}
+\fSym\minus0
+\fSym\textperiodcentered1
+\fSym\textmultiply2
+\fSym\texttimes2
+\fSym\textdivide4
+\fSym\textdiv4
+\fSym\textplusminus6
+\fSym\textpm6
+\fSym\bullet{15}
+\fCmd\textdegree{$^{\hbox{\char14}}$}%
+% FIXME @result, @expansion, @print, @equiv?
+\fSym\{{102}
+\fSym\}{103}
+\fSym\textbackslash{110}% FIXME name.
+\fSym\textsection{120}
+\fSym\textdagger{121}
+\fSym\textdaggerdbl{122}
+\fSym\textparagraph{123}
+\fSym\textbigcircle{13}
+\def\oms@textcircled#1{{\ooalign{%
+ \hfil\raise.32ex\hbox{\f@restore@enc\scalefont{600}#1}\hfil\crcr
+ \raise.35ex\hbox{\scalefont{780}\textbigcircle}}}}%
+\fCmdd\textcircled{\oms@textcircled{#1}}
+\fCmd\textregistered{\oms@textcircled{R}}
+\fCmd\copyright{\oms@textcircled{\kern-.05em C}}
+% End of OMS.
+%
+% Common glyphs of the T* encodings.
+\def\t@oenc@common{%
+\fAcc\`0
+\fAcc\'1
+\fAcc\^2
+\fAcc\~3
+\fAcc\"4
+\fAcc\H5
+\fAcc\ringaccent6
+\fAcc\v7
+\fAcc\u8
+\fAcc\=9
+\fAcc\dotaccent{10}
+\fCmpSym\dotaccent i{`\i}
+\fCmpSym\dotaccent\i{`\i}
+\fCmdd\,{\@cedilla{11}{##1}}
+\fCmdd\k{{\ooalign{\relax\f@restore@enc ##1\crcr\hidewidth\char12}}}
+\fCmdd\ogonekcentered{{\ooalign{\relax\f@restore@enc ##1\crcr\hidewidth\char12\hidewidth}}}
+\fCmp\k o{\f@restore@enc\ogonekcentered o}
+\fCmp\k O{\f@restore@enc\ogonekcentered O}
+\fSym\textquotedblleft{16}
+\fSym\textquotedblright{17}
+\fSym\textendash{21}
+\fSym\textemdash{22}
+\fCmd\textperthousand{\%\char 24 }
+\fCmd\textpertenthousand{\%\char 24\char 24 }
+\fSym\ptexi{25}
+\fSym\j{26}
+\fSym\textvisiblespace{32}
+\fCmd\textquotedbl{`\"}
+\fCmd\textdollar{`\$}
+\fSym\textquoteright{`\'}
+\fSym\textless{`\<}
+\fSym\textgreater{`\>}
+\fSym\textbackslash{92}% FIXME name.
+\fSym\textquoteleft{`\`}
+\fSym\{{123}
+\fSym\}{125}
+\fCmdd\udotaccent{\@udotaccent{##1}}
+\fCmdd\ubaraccent{\@ubaraccent{9}{##1}}
+}%
+% End of common glyphs of the T* encodings.
+%
+% T1.
+\fenc@begin{T1}
+\t@oenc@common % The common glyphs.
+\fSym\textquotesinglbase{13}% FIXME LaTeX calls it `\quotesinglbase'.
+\fSym\textguilsinglleft{14}% FIXME LaTeX calls it `\guilsinglleft'.
+\fSym\textguilsinglright{15}% FIXME LaTeX calls it `\guilsinglright'.
+\fSym\textquotedblbase{18}% FIXME LaTeX calls it `\quotedblbase'.
+\fSym\textguillemotleft{19}% FIXME LaTeX calls it `\guillemotleft'.
+\fSym\textguillemotright{20}% FIXME LaTeX calls it `\guillemotright'.
+\fCmpSym\u A{128}
+\fCmpSym\k A{129}
+\fCmpSym\'C{130}
+\fCmpSym\v C{131}
+\fCmpSym\v D{132}
+\fCmpSym\v E{133}
+\fCmpSym\k E{134}
+\fCmpSym\u G{135}
+\fCmpSym\'L{136}
+\fCmpSym\v L{137}
+\fSym\L{138}
+\fCmpSym\'N{139}
+\fCmpSym\v N{140}
+\fSym\NG{141}
+\fCmpSym\H O{142}
+\fCmpSym\'R{143}
+\fCmpSym\v R{144}
+\fCmpSym\'S{145}
+\fCmpSym\v S{146}
+\fCmpSym\,S{147}
+\fCmpSym\v T{148}
+\fCmpSym\,T{149}
+\fCmpSym\H U{150}
+\fCmpSym\ringaccent U{151}
+\fCmpSym\"Y{152}
+\fCmpSym\'Z{153}
+\fCmpSym\v Z{154}
+\fCmpSym\dotaccent Z{155}
+\fSym\IJ{156}
+\fCmpSym\dotaccent I{157}
+\fSym\dj{158}% FIXME AGL calls it dcroat.
+\fSym\textsection{159}
+\fCmpSym\u a{160}
+\fCmpSym\k a{161}
+\fCmpSym\'c{162}
+\fCmpSym\v c{163}
+\fCmpSym\v d{164}
+\fCmpSym\v e{165}
+\fCmpSym\k e{166}
+\fCmpSym\u g{167}
+\fCmpSym\'l{168}
+\fCmpSym\v l{169}
+\fSym\l{170}
+\fCmpSym\'n{171}
+\fCmpSym\v n{172}
+\fSym\ng{173}
+\fCmpSym\H o{174}
+\fCmpSym\'r{175}
+\fCmpSym\v r{176}
+\fCmpSym\'s{177}
+\fCmpSym\v s{178}
+\fCmpSym\,s{179}
+\fCmpSym\v t{180}
+\fCmpSym\,t{181}
+\fCmpSym\H u{182}
+\fCmpSym\ringaccent u{183}
+\fCmpSym\"y{184}
+\fCmpSym\'z{185}
+\fCmpSym\v z{186}
+\fCmpSym\dotaccent z{187}
+\fSym\ij{188}
+\fSym\exclamdown{189}
+\fSym\questiondown{190}
+\fSym\pounds{191}
+\fCmpSym\`A{192}
+\fCmpSym\'A{193}
+\fCmpSym\^A{194}
+\fCmpSym\~A{195}
+\fCmpSym\"A{196}
+\fCmpSym\ringaccent A{197}
+\fSym\AE{198}
+\fCmpSym\,C{199}
+\fCmpSym\`E{200}
+\fCmpSym\'E{201}
+\fCmpSym\^E{202}
+\fCmpSym\"E{203}
+\fCmpSym\`I{204}
+\fCmpSym\'I{205}
+\fCmpSym\^I{206}
+\fCmpSym\"I{207}
+\fSym\DH{208}% FIXME AGL calls it eth.
+\fSym\DJ{208}% FIXME AGL calls it dcroat.
+\fCmpSym\~N{209}
+\fCmpSym\`O{210}
+\fCmpSym\'O{211}
+\fCmpSym\^O{212}
+\fCmpSym\~O{213}
+\fCmpSym\"O{214}
+\fSym\OE{215}
+\fSym\O{216}
+\fCmpSym\`U{217}
+\fCmpSym\'U{218}
+\fCmpSym\^U{219}
+\fCmpSym\"U{220}
+\fCmpSym\'Y{221}
+\fSym\TH{222}% FIXME AGL calls it thorn.
+\fSym\SS{223}
+\fCmpSym\`a{224}
+\fCmpSym\'a{225}
+\fCmpSym\^a{226}
+\fCmpSym\~a{227}
+\fCmpSym\"a{228}
+\fCmpSym\ringaccent a{229}
+\fSym\ae{230}
+\fCmpSym\,c{231}
+\fCmpSym\`e{232}
+\fCmpSym\'e{233}
+\fCmpSym\^e{234}
+\fCmpSym\"e{235}
+\fCmpSym\`i{236}
+\fCmpSym\'i{237}
+\fCmpSym\^i{238}
+\fCmpSym\"i{239}
+\fSym\dh{240}% FIXME AGL calls it eth.
+\fCmpSym\~n{241}
+\fCmpSym\`o{242}
+\fCmpSym\'o{243}
+\fCmpSym\^o{244}
+\fCmpSym\~o{245}
+\fCmpSym\"o{246}
+\fSym\oe{247}
+\fSym\o{248}
+\fCmpSym\`u{249}
+\fCmpSym\'u{250}
+\fCmpSym\^u{251}
+\fCmpSym\"u{252}
+\fCmpSym\'y{253}
+\fSym\th{254}% FIXME AGL calls it thorn.
+\fSym\ss{255}
+% End of T1.
+%
+% T2A.
+\fenc@begin{T2A}
+\t@oenc@common % The common glyphs.
+\fSym\CYRpalochka{13}
+\fAcc\f{18}
+\fAcc\C{19}
+\fAcc\U{20}
+\fSym\textnumero{157}
+\fSym\textsection{158}
+\fSym\textquotedblbase{189}% FIXME LaTeX calls this \quotedblbase.
+\fSym\textguillemotleft{190}% FIXME LaTeX calls it `\guillemotleft'.
+\fSym\textguillemotright{191}% FIXME LaTeX calls it `\guillemotright'.
+\fSym\CYRA{192}
+\fSym\cyra{224}
+\fSym\CYRB{193}
+\fSym\cyrb{225}
+\fSym\CYRV{194}
+\fSym\cyrv{226}
+\fSym\CYRG{195}
+\fSym\cyrg{227}
+\fSym\CYRD{196}
+\fSym\cyrd{228}
+\fSym\CYRE{197}
+\fSym\cyre{229}
+\fSym\CYRZH{198}
+\fSym\cyrzh{230}
+\fSym\CYRZ{199}
+\fSym\cyrz{231}
+\fSym\CYRI{200}
+\fSym\cyri{232}
+\fSym\CYRISHRT{201}
+\fSym\cyrishrt{233}
+\fSym\CYRK{202}
+\fSym\cyrk{234}
+\fSym\CYRL{203}
+\fSym\cyrl{235}
+\fSym\CYRM{204}
+\fSym\cyrm{236}
+\fSym\CYRN{205}
+\fSym\cyrn{237}
+\fSym\CYRO{206}
+\fSym\cyro{238}
+\fSym\CYRP{207}
+\fSym\cyrp{239}
+\fSym\CYRR{208}
+\fSym\cyrr{240}
+\fSym\CYRS{209}
+\fSym\cyrs{241}
+\fSym\CYRT{210}
+\fSym\cyrt{242}
+\fSym\CYRU{211}
+\fSym\cyru{243}
+\fSym\CYRF{212}
+\fSym\cyrf{244}
+\fSym\CYRH{213}
+\fSym\cyrh{245}
+\fSym\CYRC{214}
+\fSym\cyrc{246}
+\fSym\CYRCH{215}
+\fSym\cyrch{247}
+\fSym\CYRSH{216}
+\fSym\cyrsh{248}
+\fSym\CYRSHCH{217}
+\fSym\cyrshch{249}
+\fSym\CYRHRDSN{218}
+\fSym\cyrhrdsn{250}
+\fSym\CYRERY{219}
+\fSym\cyrery{251}
+\fSym\CYRSFTSN{220}
+\fSym\cyrsftsn{252}
+\fSym\CYREREV{221}
+\fSym\cyrerev{253}
+\fSym\CYRYU{222}
+\fSym\cyryu{254}
+\fSym\CYRYA{223}
+\fSym\cyrya{255}
+\fSym\CYRGUP{128}
+\fSym\cyrgup{160}
+\fSym\CYRGHCRS{129}
+\fSym\cyrghcrs{161}
+\fSym\CYRDJE{130}
+\fSym\cyrdje{162}
+\fSym\CYRTSHE{131}
+\fSym\cyrtshe{163}
+\fSym\CYRSHHA{132}
+\fSym\cyrshha{164}
+\fSym\CYRZHDSC{133}
+\fSym\cyrzhdsc{165}
+\fSym\CYRZDSC{134}
+\fSym\cyrzdsc{166}
+\fSym\CYRLJE{135}
+\fSym\cyrlje{167}
+\fSym\CYRYI{136}
+\fSym\cyryi{168}
+\fSym\CYRKDSC{137}
+\fSym\cyrkdsc{169}
+\fSym\CYRKBEAK{138}
+\fSym\cyrkbeak{170}
+\fSym\CYRKVCRS{139}
+\fSym\cyrkvcrs{171}
+\fSym\CYRAE{140}
+\fSym\cyrae{172}
+\fSym\CYRNDSC{141}
+\fSym\cyrndsc{173}
+\fSym\CYRNG{142}
+\fSym\cyrng{174}
+\fSym\CYRDZE{143}
+\fSym\cyrdze{175}
+\fSym\CYROTLD{144}
+\fSym\cyrotld{176}
+\fSym\CYRSDSC{145}
+\fSym\cyrsdsc{177}
+\fSym\CYRUSHRT{146}
+\fSym\cyrushrt{178}
+\fSym\CYRY{147}
+\fSym\cyry{179}
+\fSym\CYRYHCRS{148}
+\fSym\cyryhcrs{180}
+\fSym\CYRHDSC{149}
+\fSym\cyrhdsc{181}
+\fSym\CYRDZHE{150}
+\fSym\cyrdzhe{182}
+\fSym\CYRCHVCRS{151}
+\fSym\cyrchvcrs{183}
+\fSym\CYRCHRDSC{152}
+\fSym\cyrchrdsc{184}
+\fSym\CYRIE{153}
+\fSym\cyrie{185}
+\fSym\CYRSCHWA{154}
+\fSym\cyrschwa{186}
+\fSym\CYRNJE{155}
+\fSym\cyrnje{187}
+\fSym\CYRYO{156}
+\fSym\cyryo{188}
+\fSym\CYRII{73}
+\fSym\cyrii{105}
+\fSym\CYRJE{74}
+\fSym\cyrje{106}
+\fSym\CYRQ{81}
+\fSym\cyrq{113}
+\fSym\CYRW{87}
+\fSym\cyrw{119}
+\fCmpSym\"\CYRE{156}
+\fCmpSym\"\cyre{188}
+\fCmpSym\U\CYRI{201}
+\fCmpSym\U\cyri{233}
+\fCmpSym\"\CYRII{136}
+\fCmpSym\"\cyrii{168}
+\fCmpSym\,\CYRZ{134}
+\fCmpSym\,\cyrz{166}
+\fCmpSym\k\CYRS{145}
+\fCmpSym\k\cyrs{177}
+\fCmpSym\U\CYRU{146}
+\fCmpSym\U\cyru{178}
+% End of T2A.
+%
+% TS1.
+\fenc@begin{TS1}
+\fAcc\tieaccent{26}
+\fCmd\textdollar{`\$}
+\fSym\textfractionsolidus{47}
+\fSym\minus{61}
+\fSym\textbigcircle{79}
+\fCmdd\textcircled{{\ooalign{\hfil\raise.34ex%
+ \hbox{\f@restore@enc\scalefont{560}#1}\hfil\crcr\hbox{\textbigcircle}}}}
+%\fSym\star{98}% FIXME this requires redefining \point.
+\fSym\textdagger{132}
+\fSym\textdaggerdbl{133}
+\fSym\textperthousand{135}
+\fSym\bullet{136}
+\fSym\texttrademark{151}
+\fSym\textpertenthousand{152}
+\fSym\textnumero{155}
+\fSym\textcent{162}
+\fSym\pounds{163}
+\fSym\textcurrency{164}
+\fSym\textyen{165}
+\fSym\textbrokenbar{166}
+\fSym\textsection{167}
+\fSym\copyright{169}
+\fSym\ordf{170}
+\fSym\textlnot{172}% FIXME What about \lnot?
+\fSym\textregistered{174}
+\fSym\textdegree{176}
+\fSym\textplusminus{177}
+\fSym\textpm{177}
+\fSym\texttwosuperior{178}
+\fSym\textthreesuperior{179}
+\fSym\textmu{181}
+\fSym\textparagraph{182}
+\fSym\textperiodcentered{183}
+\fSym\textonesuperior{185}
+\fSym\ordm{186}
+\fSym\textonequarter{188}
+\fSym\textonehalf{189}
+\fSym\textthreequarters{190}
+\fSym\euro{191}
+\fSym\textmultiply{214}
+\fSym\texttimes{214}
+\fSym\textdivide{246}
+\fSym\textdiv{246}
+% End of TS1.
+%
+% Free the memory.
+\let\t@oenc@common\undefined
+%
+\endinput
diff --git a/contrib/texifont/otest.tex b/contrib/texifont/otest.tex
new file mode 100644
index 0000000..3ef337a
--- /dev/null
+++ b/contrib/texifont/otest.tex
@@ -0,0 +1,157 @@
+\catcode`\@=11
+\input ienc
+\input oenc
+\input fsel
+
+
+%\tracingfonts2
+\def\msg#1{\medskip\leftline{#1}\message{^^J^^J** #1}\ignorespaces}
+
+
+
+\msg{Copyright and registered}
+
+x\copyright\ x\registeredsymbol
+
+{\setfontencoding{T1}\setfontfamily{LMRoman}\selectfont
+x\copyright\ x\registeredsymbol}
+
+
+
+% Declare a test font family, with very different fonts (visually) for
+% OT1 and T1.
+\declarefontfamily TestFam 1000 1200
+\fontmapfamily TestFam OT1 CMSans
+\fontmapfamily TestFam T1 URWPalladio
+\fontmapfamily TestFam TS1 LMRoman
+\fontmapfamily TestFam OML CMRoman
+\fontmapfamily TestFam OMS CMRoman
+\fontmapfamily TestFam T2A LHRoman
+
+% Define some encoding-specific glyphs.
+\fenc@begin{OT1}
+\fAcc\a{19}% \'
+\fCmp\a e{\'e}
+\fCmp\a E{\f@restore@enc\'e}
+\fCmp\a g{\'g}
+\fCmp\a G{\f@restore@enc\'g}
+\fCmp\a m{\b{oo}}
+\fCmp\a M{\f@restore@enc\b{oo}}
+\fCmp\a n{\b \copyright}
+\fCmp\a N{\f@restore@enc\b \copyright}
+\fCmd\copyright{WrongEncoding}
+%
+\fenc@begin{OML}
+\fAcc\b{127}% \tieafter
+
+\catcode`\@=12
+
+
+
+\msg{Dollar, pounds, euro (in OT1)}
+
+\textdollar{\itshape\textdollar}
+{\bfseries\textdollar{\itshape\textdollar}}
+
+% There's no bold `ui' font, so we don't get a bold \pounds.
+\pounds{\itshape\pounds}
+{\bfseries\pounds{\itshape\pounds}}
+
+\euro{\itshape\euro}
+{\bfseries\euro{\itshape\euro}}
+
+
+
+\msg{Cache}
+% To see this test working, you must uncomment the messages in
+% \f@search@command and \f@search@composite (but this will break
+% accents, so for other test comment them out again).
+
+% The cache is global and does not depend on font shape.
+{\bf
+ \textregistered\textless\'a\texttimes\'g \tieaccent{oo}
+ \message{^^J*}
+}\quad
+\textregistered\textless\'a\texttimes\'g \tieaccent{oo}
+\message{^^J**}
+
+\documentencoding ISO-8859-1
+% Now the new cache will be filled because \documentencoding changed
+% the current font encoding list.
+{\bf
+ \textregistered\textless\'a\texttimes\'g \tieaccent{oo}
+ \message{^^J*}
+}\quad
+\textregistered\textless\'a\texttimes\'g \tieaccent{oo}
+\message{^^J**}
+
+\setfontencoding{T1}\setfontfamily{TestFam}\selectfont
+% Again, another cache because encodings list of TestFam is different
+% from that of CMRoman.
+{\bf
+ \textregistered\textless\'a\texttimes\'g \tieaccent{oo} \CYRZH
+ \message{^^J*}
+}\quad
+\textregistered\textless\'a\texttimes\'g \tieaccent{oo} \CYRZH
+\message{^^J**}
+
+
+% We are now in ISO-8859-1 input encoding and T1 encoding of TestFam.
+
+
+\msg{Accents}
+\'{}
+\'a
+\'ô
+\'\copyright
+\quad
+% |a| in T1 (the current encoding), the accent in OT1 (the only
+% encoding containing |\a|).
+\a a
+\a ô
+\a \copyright
+\quad
+% Argument of the accent can contain an expandable command (including
+% an active character) only as a first token. But even then, it's
+% best if it's the only token in the argument, because |\bf a| and
+% |\bfa| will not be distinguished by the cache.
+\a{\bf c}
+%\a{\bf ô}% Doesn't work.
+\def\boldohat{\bf ô}%
+\a\boldohat
+%\a{\bf \ae}% Doesn't work.
+\def\boldae{\bf\ae}%
+\a\boldae
+
+
+
+\msg{Composites}
+\'e
+\'g
+\quad
+% Improperly defined composite -- |\a e| does not restore the original
+% encoding before calling another glyph macro (|\'e|), which results
+% in |e| being typeset in the encoding of the |\a e| composite (OT1).
+\a e
+\a g
+% Now the original encoding is properly restored -- therefore |\'e|
+% is called from T1; since T1 contains the composite |\'e|, we get
+% that. For |\'g| we get an accent since there's no such composite.
+\a E
+\a G
+\quad
+% A more complex example with the actual accent coming from yet
+% another encoding.
+\a m
+\a M
+\quad
+% And now even the accent's argument is from a different encoding.
+\a n
+\a N
+
+\bye
+
+% Local variables:
+% compile-command: "tex --interact=nonstopmode otest.tex"
+% coding: latin-1
+% End:
diff --git a/contrib/texifont/sample.cp1251 b/contrib/texifont/sample.cp1251
new file mode 100644
index 0000000..66bb18d
--- /dev/null
+++ b/contrib/texifont/sample.cp1251
@@ -0,0 +1,24 @@
+% -*- mode: TeX; coding: cp1251; -*-
+% From http://www.unicode.org/standard/translations/russian.html
+Ïî ñâîåé ïðèðîäå êîìïüþòåðû ìîãóò ðàáîòàòü ëèøü ñ ÷èñëàìè. È äëÿ òîãî,
+÷òîáû îíè ìîãëè õðàíèòü â ïàìÿòè áóêâû èëè äðóãèå ñèìâîëû, êàæäîìó
+òàêîìó ñèìâîëó äîëæíî áûòü ïîñòàâëåíî â ñîîòâåòñòâèå ÷èñëî. Äî òîãî,
+êàê ïîÿâèëñÿ Unicode, â ìèðå èìåëè õîæäåíèå ñîòíè ðàçëè÷íûõ ñõåì
+ïîäîáíîãî êîäèðîâàíèÿ ñèìâîëîâ. Íî íè îäíà èç ýòèõ ñõåì íå áûëà ñòîëü
+óíèâåðñàëüíîé, ÷òîáû îïèñàòü âñå íåîáõîäèìûå ñèìâîëû: íàïðèìåð, òîëüêî
+äëÿ êîäèðîâàíèÿ áóêâ, âõîäÿùèõ â àëôàâèòû ÿçûêîâ Åâðîïåéñêîãî
+Ñîîáùåñòâà, íåîáõîäèìî áûëî èñïîëüçîâàòü íåñêîëüêî ðàçëè÷íûõ
+êîäèðîâîê. Ïî áîëüøîìó ñ÷¸òó äàæå è äëÿ îòäåëüíîãî ÿçûêà, ñêàæåì,
+àíãëèéñêîãî, íå ñóùåñòâîâàëî åäèíîé ñèñòåìû êîäèðîâàíèÿ, âêëþ÷àâøåé â
+ñåáÿ âñå îáû÷íî èñïîëüçóåìûå áóêâû, çíàêè ïóíêòóàöèè è òåõíè÷åñêèå
+ñèìâîëû.
+
+Áîëåå òîãî, âñå ýòè ñõåìû êîäèðîâàíèÿ ÷àñòî äàæå íå áûëè ñîâìåñòèìû
+äðóã ñ äðóãîì. Ê ïðèìåðó, äâå ðàçíûå êîäèðîâêè ìîãëè èñïîëüçîâàòü îäèí
+è òîò æå êîä äëÿ ïðåäñòàâëåíèÿ äâóõ ðàçíûõ ñèìâîëîâ èëè ïðèñâàèâàòü
+ðàçíûå êîäû îäíîé è òîé æå áóêâå. Â ýòîé ñèòóàöèè äëÿ ëþáîãî
+êîìïüþòåðà, à îñîáåííî ñåðâåðà, ïðèõîäèëîñü ïîääåðæèâàòü íåñêîëüêî
+ðàçíûõ êîäèðîâîê, êîòîðûå ìîãëè ïîíàäîáèòüñÿ, íî äàæå è òîãäà ïðè
+ïåðåäà÷å äàííûõ íà äðóãóþ ïëàòôîðìó èëè ïðè èõ ïðåîáðàçîâàíèè â äðóãóþ
+êîäèðîâêó âñåãäà îñòàâàëñÿ ðèñê, ÷òî ýòè äàííûå îêàæóòñÿ ïîâðåæä¸ííûìè.
+\endinput
diff --git a/contrib/texifont/sample.koi8r b/contrib/texifont/sample.koi8r
new file mode 100644
index 0000000..d8db28b
--- /dev/null
+++ b/contrib/texifont/sample.koi8r
@@ -0,0 +1,24 @@
+% -*- mode: TeX; coding: koi8-r; -*-
+% From http://www.unicode.org/standard/translations/russian.html
+ðÏ Ó×ÏÅÊ ÐÒÉÒÏÄÅ ËÏÍÐØÀÔÅÒÙ ÍÏÇÕÔ ÒÁÂÏÔÁÔØ ÌÉÛØ Ó ÞÉÓÌÁÍÉ. é ÄÌÑ ÔÏÇÏ,
+ÞÔÏÂÙ ÏÎÉ ÍÏÇÌÉ ÈÒÁÎÉÔØ × ÐÁÍÑÔÉ ÂÕË×Ù ÉÌÉ ÄÒÕÇÉÅ ÓÉÍ×ÏÌÙ, ËÁÖÄÏÍÕ
+ÔÁËÏÍÕ ÓÉÍ×ÏÌÕ ÄÏÌÖÎÏ ÂÙÔØ ÐÏÓÔÁ×ÌÅÎÏ × ÓÏÏÔ×ÅÔÓÔ×ÉÅ ÞÉÓÌÏ. äÏ ÔÏÇÏ,
+ËÁË ÐÏÑ×ÉÌÓÑ Unicode, × ÍÉÒÅ ÉÍÅÌÉ ÈÏÖÄÅÎÉÅ ÓÏÔÎÉ ÒÁÚÌÉÞÎÙÈ ÓÈÅÍ
+ÐÏÄÏÂÎÏÇÏ ËÏÄÉÒÏ×ÁÎÉÑ ÓÉÍ×ÏÌÏ×. îÏ ÎÉ ÏÄÎÁ ÉÚ ÜÔÉÈ ÓÈÅÍ ÎÅ ÂÙÌÁ ÓÔÏÌØ
+ÕÎÉ×ÅÒÓÁÌØÎÏÊ, ÞÔÏÂÙ ÏÐÉÓÁÔØ ×ÓÅ ÎÅÏÂÈÏÄÉÍÙÅ ÓÉÍ×ÏÌÙ: ÎÁÐÒÉÍÅÒ, ÔÏÌØËÏ
+ÄÌÑ ËÏÄÉÒÏ×ÁÎÉÑ ÂÕË×, ×ÈÏÄÑÝÉÈ × ÁÌÆÁ×ÉÔÙ ÑÚÙËÏ× å×ÒÏÐÅÊÓËÏÇÏ
+óÏÏÂÝÅÓÔ×Á, ÎÅÏÂÈÏÄÉÍÏ ÂÙÌÏ ÉÓÐÏÌØÚÏ×ÁÔØ ÎÅÓËÏÌØËÏ ÒÁÚÌÉÞÎÙÈ
+ËÏÄÉÒÏ×ÏË. ðÏ ÂÏÌØÛÏÍÕ ÓÞ£ÔÕ ÄÁÖÅ É ÄÌÑ ÏÔÄÅÌØÎÏÇÏ ÑÚÙËÁ, ÓËÁÖÅÍ,
+ÁÎÇÌÉÊÓËÏÇÏ, ÎÅ ÓÕÝÅÓÔ×Ï×ÁÌÏ ÅÄÉÎÏÊ ÓÉÓÔÅÍÙ ËÏÄÉÒÏ×ÁÎÉÑ, ×ËÌÀÞÁ×ÛÅÊ ×
+ÓÅÂÑ ×ÓÅ ÏÂÙÞÎÏ ÉÓÐÏÌØÚÕÅÍÙÅ ÂÕË×Ù, ÚÎÁËÉ ÐÕÎËÔÕÁÃÉÉ É ÔÅÈÎÉÞÅÓËÉÅ
+ÓÉÍ×ÏÌÙ.
+
+âÏÌÅÅ ÔÏÇÏ, ×ÓÅ ÜÔÉ ÓÈÅÍÙ ËÏÄÉÒÏ×ÁÎÉÑ ÞÁÓÔÏ ÄÁÖÅ ÎÅ ÂÙÌÉ ÓÏ×ÍÅÓÔÉÍÙ
+ÄÒÕÇ Ó ÄÒÕÇÏÍ. ë ÐÒÉÍÅÒÕ, Ä×Å ÒÁÚÎÙÅ ËÏÄÉÒÏ×ËÉ ÍÏÇÌÉ ÉÓÐÏÌØÚÏ×ÁÔØ ÏÄÉÎ
+É ÔÏÔ ÖÅ ËÏÄ ÄÌÑ ÐÒÅÄÓÔÁ×ÌÅÎÉÑ Ä×ÕÈ ÒÁÚÎÙÈ ÓÉÍ×ÏÌÏ× ÉÌÉ ÐÒÉÓ×ÁÉ×ÁÔØ
+ÒÁÚÎÙÅ ËÏÄÙ ÏÄÎÏÊ É ÔÏÊ ÖÅ ÂÕË×Å. ÷ ÜÔÏÊ ÓÉÔÕÁÃÉÉ ÄÌÑ ÌÀÂÏÇÏ
+ËÏÍÐØÀÔÅÒÁ, Á ÏÓÏÂÅÎÎÏ ÓÅÒ×ÅÒÁ, ÐÒÉÈÏÄÉÌÏÓØ ÐÏÄÄÅÒÖÉ×ÁÔØ ÎÅÓËÏÌØËÏ
+ÒÁÚÎÙÈ ËÏÄÉÒÏ×ÏË, ËÏÔÏÒÙÅ ÍÏÇÌÉ ÐÏÎÁÄÏÂÉÔØÓÑ, ÎÏ ÄÁÖÅ É ÔÏÇÄÁ ÐÒÉ
+ÐÅÒÅÄÁÞÅ ÄÁÎÎÙÈ ÎÁ ÄÒÕÇÕÀ ÐÌÁÔÆÏÒÍÕ ÉÌÉ ÐÒÉ ÉÈ ÐÒÅÏÂÒÁÚÏ×ÁÎÉÉ × ÄÒÕÇÕÀ
+ËÏÄÉÒÏ×ËÕ ×ÓÅÇÄÁ ÏÓÔÁ×ÁÌÓÑ ÒÉÓË, ÞÔÏ ÜÔÉ ÄÁÎÎÙÅ ÏËÁÖÕÔÓÑ ÐÏ×ÒÅÖÄ£ÎÎÙÍÉ.
+\endinput
diff --git a/contrib/texifont/sample.latin1 b/contrib/texifont/sample.latin1
new file mode 100644
index 0000000..79f39dd
--- /dev/null
+++ b/contrib/texifont/sample.latin1
@@ -0,0 +1,18 @@
+% -*- mode: TeX; coding: latin-1; -*-
+% From http://www.unicode.org/standard/translations/icelandic.html
+Tölvur geta í eðli sínu aðeins unnið með tölur. Þær geyma bókstafi og
+önnur skriftákn með því að úthluta þeim tölu. Áður en Unicode kom til
+voru hundruð mismunandi túlkunarkerfa sem úthlutuðu þessum
+tölum. Ekkert eitt túlkunarkerfi gat innihaldið nægilegan fjölda
+skriftákna; t.d. þarfnast Evrópusambandið nokkurra mismunandi kerfa
+til að spanna öll tungumál þess. Jafnvel fyrir eitt tungumál, eins og
+ensku, var eitt túlkunarkerfi ekki nóg fyrir alla bókstafi,
+greinarmerki og algengustu einingatákn.
+
+Túlkunarkerfin hafa einnig verið í andstöðu hvert við annað, þ.e. tvö
+kerfi geta notað sömu tölu fyrir tvö ólík skriftákn eða notað tvær
+mismunandi tölur fyrir sama táknið. Sérhver tölva þarf (sérstaklega
+miðlarar) að styðja margs konar túlkanir á stöfum; engu að síður er
+alltaf hætta á stafabrenglun þegar gögn fara á milli tölva og á milli
+mismunandi túlkunarkerfa.
+\endinput
diff --git a/contrib/texifont/sample.latin2 b/contrib/texifont/sample.latin2
new file mode 100644
index 0000000..eb29f8a
--- /dev/null
+++ b/contrib/texifont/sample.latin2
@@ -0,0 +1,18 @@
+% -*- mode: TeX; coding: latin-2; -*-
+% From http://www.unicode.org/standard/translations/czech.html
+Poèítaèe, ze své podstaty, pracují pouze s èísly. Písmena a dal¹í
+znaky ukládají tak, ¾e ka¾dému z nich pøiøadí èíslo. Pøed vznikem
+Unicode existovaly stovky rozdílných kódovacích systémù pro
+pøiøazování tìchto èísel. ®ádné z tìchto kódování nemohlo obsahovat
+dostatek znakù: napøíklad Evropská unie sama potøebuje nìkolik rùzných
+kódování, aby pokryla v¹echny své jazyky. Dokonce i pro jeden jediný
+jazyk, jako je angliètina, nevyhovovalo ¾ádné kódování pro v¹echny
+písmena, interpunkci a bì¾nì pou¾ívané technické symboly.
+
+Tyto kódovací systémy také byly v konfliktu jeden s druhým. To
+znamená, ¾e dvì kódování mohou pou¾ívat stejné èíslo pro dva rùzné
+znaky, nebo pou¾ívat rùzná èísla pro stejný znak. Jakýkoli poèítaè
+(zvlá¹tì servery) musí podporovat mnoho rùzných kódování; pøesto,
+kdykoli jsou data pøedávána mezi rùznými kódováními nebo platformami,
+hrozí, ¾e tato data budou po¹kozena.
+\endinput
diff --git a/contrib/texifont/sample.latin9 b/contrib/texifont/sample.latin9
new file mode 100644
index 0000000..47f8193
--- /dev/null
+++ b/contrib/texifont/sample.latin9
@@ -0,0 +1,19 @@
+% -*- mode: TeX; coding: latin-9; -*-
+% From http://www.unicode.org/standard/translations/french.html
+Fondamentalement, les ordinateurs ne comprennent que les nombres. Ils
+codent les lettres et autres caractères sous formes de nombres. Avant
+l'invention d'Unicode, des centaines de systèmes de codage de
+caractères ont été créés. Pas un seul d'entre eux n'était satisfaisant:
+par exemple, l'Union Européenne a besoin de plusieurs systèmes de
+codage pour couvrir toutes ses langues d'usage. Même pour une seule
+langue comme le français, aucun système de codage ne couvrait toutes
+les lettres, les signes de ponctuation et les symboles techniques en
+usage courant.
+
+Ces systèmes de codage sont souvent incompatibles entre eux. Ainsi,
+deux systèmes peuvent utiliser le même nombre pour deux caractères
+différents ou utiliser différents nombres pour le même caractère. Les
+ordinateurs, et plus particulièrement les serveurs, doivent supporter
+plusieurs systèmes de codage de caractères, ce qui crée un risque de
+corruption des données à chaque transition.
+\endinput
diff --git a/contrib/texifont/tests/Makefile b/contrib/texifont/tests/Makefile
new file mode 100644
index 0000000..7355fa4
--- /dev/null
+++ b/contrib/texifont/tests/Makefile
@@ -0,0 +1,29 @@
+TEX=tex
+DIFF=diff
+
+define run_test
+$(TEX) $@.tex 2>&1 \
+ | $(DIFF) -u -I '^This is TeX, Version 3\..*' $@.out -
+endef
+
+$(foreach target,newfont subst,$def_test)
+
+define def_test
+all: $(target)
+$(target)::
+ $(run_test)
+endef
+
+#.PHONY: all
+#
+#$(call def_test,newfont)
+#
+#all: newfont
+#
+#all: subst
+#
+#newfont::
+# $(run_test)
+#
+#subst::
+# $(run_test)
diff --git a/contrib/texifont/tests/newfont.out b/contrib/texifont/tests/newfont.out
new file mode 100644
index 0000000..57636a2
--- /dev/null
+++ b/contrib/texifont/tests/newfont.out
@@ -0,0 +1,76 @@
+This is TeX, Version 3.141592 (Web2C 7.5.6)
+(./newfont.tex (../fattr.tex (/usr/share/texmf-texlive/tex/eplain/eplain.tex))
+
+**** Simple font defs.
+17: Started font def with "\do 8.0pt 1000 {a8}".
+
+18: Updated font def to "\do 8.0pt 1000 {a8}\do 10.0pt 1000 {a10}".
+
+19: Updated font def to "\do 8.0pt 1000 {a8}\do 10.0pt 1000 {a10}\do 12.0pt 100
+0 {a12}".
+
+21: Warning: Replacing font "a12" (12.0pt@1000) with font "b12" (12.0pt@1000).
+
+21: Updated font def to "\do 8.0pt 1000 {a8}\do 10.0pt 1000 {a10}\do 12.0pt 100
+0 {b12}".
+
+22: Warning: Replacing font "a10" (10.0pt@1000) with font "b10" (10.0pt@1000).
+
+22: Updated font def to "\do 8.0pt 1000 {a8}\do 10.0pt 1000 {b10}\do 12.0pt 100
+0 {b12}".
+
+23: Warning: Replacing font "a8" (8.0pt@1000) with font "b8" (8.0pt@1000).
+
+23: Updated font def to "\do 8.0pt 1000 {b8}\do 10.0pt 1000 {b10}\do 12.0pt 100
+0 {b12}".
+**** Simple font defs with mag factor variations.
+
+27: Started font def with "\do 12.0pt 1000 {c12}".
+
+28: Updated font def to "\do 8.0pt 1000 {c8}\do 12.0pt 1000 {c12}".
+
+29: Updated font def to "\do 8.0pt 1000 {c8}\do 10.0pt 1000 {c10}\do 12.0pt 100
+0 {c12}".
+
+31: Updated font def to "\do 8.0pt 1000 {c8}\do 10.0pt 1000 {c10}\do 10.0pt 120
+0 {c10}\do 12.0pt 1000 {c12}".
+
+32: Updated font def to "\do 8.0pt 1000 {c8}\do 10.0pt 1000 {c10}\do 10.0pt 120
+0 {c10}\do 12.0pt 1000 {c12}\do 12.0pt 1100 {c12}".
+
+33: Updated font def to "\do 8.0pt 1000 {c8}\do 10.0pt 1000 {c10}\do 8.0pt 1300
+ {c8}\do 10.0pt 1200 {c10}\do 12.0pt 1000 {c12}\do 12.0pt 1100 {c12}".
+
+**** Same design size and mag factor, different feature sets.
+
+37: Started font def with "\do 10.0pt 1000 {d10}".
+
+38: Started font def with "\do 10.0pt 1000 {d10}".
+
+39: Started font def with "\do 10.0pt 1000 {d10}".
+
+40: Started font def with "\do 10.0pt 1000 {d10}".
+
+41: Started font def with "\do 10.0pt 1000 {d10}".
+
+42: Started font def with "\do 10.0pt 1000 {d10}".
+
+**** Same design size, different mag factors.
+
+46: Started font def with "\do 10.0pt 1000 {e1.0}".
+
+47: Updated font def to "\do 10.0pt 1000 {e1.0}\do 10.0pt 1400 {e1.4}".
+
+48: Updated font def to "\do 10.0pt 800 {e0.8}\do 10.0pt 1000 {e1.0}\do 10.0pt
+1400 {e1.4}".
+50: Started font def with "\do 10.0pt 1000 {f1.0}".
+
+51: Updated font def to "\do 10.0pt 800 {f0.8}\do 10.0pt 1000 {f1.0}".
+
+52: Updated font def to "\do 10.0pt 800 {f0.8}\do 10.0pt 1000 {f1.0}\do 10.0pt
+1400 {f1.4}".
+
+53: Updated font def to "\do 10.0pt 800 {f0.8}\do 10.0pt 1000 {f1.0}\do 10.0pt
+1200 {f1.2}\do 10.0pt 1400 {f1.4}". )
+No pages of output.
+Transcript written on newfont.log.
diff --git a/contrib/texifont/tests/newfont.tex b/contrib/texifont/tests/newfont.tex
new file mode 100644
index 0000000..2934eef
--- /dev/null
+++ b/contrib/texifont/tests/newfont.tex
@@ -0,0 +1,55 @@
+\input ../fattr
+
+\ftracelevel=3
+
+\newfontattr family Fam1
+\newfontattr family Fam2
+\newfontattr family Fam3
+\newfontattr encoding Enc1
+\newfontattr encoding Enc2
+\newfontattr encoding Enc3
+\newfontattr encoding Enc4
+\newfontattr slant Slant1
+\newfontattr slant Slant2
+
+\message{^^J**** Simple font defs.}
+
+\newfont 8 1000 a8 Fam1
+\newfont 10 1000 a10 Fam1
+\newfont 12 1000 a12 Fam1
+
+\newfont 12 1000 b12 Fam1
+\newfont 10 1000 b10 Fam1
+\newfont 8 1000 b8 Fam1
+
+\message{^^J**** Simple font defs with mag factor variations.}
+
+\newfont 12 1000 c12 Fam1,Enc1
+\newfont 8 1000 c8 Enc1,Fam1
+\newfont 10 1000 c10 Fam1,Enc1
+
+\newfont 10 1200 c10 Fam1,Enc1
+\newfont 12 1100 c12 Fam1,Enc1
+\newfont 8 1300 c8 Fam1,Enc1
+
+\message{^^J**** Same design size and mag factor, different feature sets.}
+
+\newfont 10 1000 d10 Fam2
+\newfont 10 1000 d10 Fam2,Enc2
+\newfont 10 1000 d10 Fam1,Enc2
+\newfont 10 1000 d10 Fam1,Enc3
+\newfont 10 1000 d10 Fam1,Enc2,Slant1
+\newfont 10 1000 d10 Fam1,Slant2,Enc2
+
+\message{^^J**** Same design size, different mag factors.}
+
+\newfont 10 1000 e1.0 Fam3
+\newfont 10 1400 e1.4 Fam3
+\newfont 10 800 e0.8 Fam3
+
+\newfont 10 1000 f1.0 Fam3,Enc4
+\newfont 10 800 f0.8 Fam3,Enc4
+\newfont 10 1400 f1.4 Fam3,Enc4
+\newfont 10 1200 f1.2 Fam3,Enc4
+
+\bye
diff --git a/contrib/texifont/tests/subst.tex b/contrib/texifont/tests/subst.tex
new file mode 100644
index 0000000..fb9ee38
--- /dev/null
+++ b/contrib/texifont/tests/subst.tex
@@ -0,0 +1,21 @@
+\input ../fattr
+
+\ftracelevel=3
+
+\newfontattr family Fam1
+\newfontattr family Fam2
+\newfontattr family Fam3
+\newfontattr encoding Enc1
+\newfontattr encoding Enc2
+\newfontattr encoding Enc3
+\newfontattr encoding Enc4
+\newfontattr slant Slant1
+\newfontattr slant Slant2
+\newfontattr slant Slant3
+\newfontattr slant Slant4
+
+\fontsubstpre = Fam1
+ - slant
+ + Enc1
+
+\bye
diff --git a/contrib/texifont/texifont.pdf b/contrib/texifont/texifont.pdf
new file mode 100644
index 0000000..1ef7d7f
--- /dev/null
+++ b/contrib/texifont/texifont.pdf
Binary files differ
diff --git a/contrib/texifont/texifont.txi b/contrib/texifont/texifont.txi
new file mode 100644
index 0000000..42b820c
--- /dev/null
+++ b/contrib/texifont/texifont.txi
@@ -0,0 +1,680 @@
+\input texinfo.tex @c -*-texinfo-*-
+@setfilename texifont
+@settitle GNU Texinfo font subsystem
+
+@c Originally written by Oleg Katsidatze and Karl Berry, 2006.
+@c Public domain.
+
+@syncodeindex fn cp
+
+@titlepage
+@title GNU Texinfo font subsystem
+@end titlepage
+
+
+@contents
+
+
+@ifnottex
+@node Top
+@top GNU Texinfo font subsystem
+
+Unfinished chapter on GNU Texinfo font subsystem, also unfinished.
+@end ifnottex
+
+@menu
+* Font management:: Defining font families.
+* Index::
+@end menu
+
+
+@node Font management
+@chapter Font management
+
+Texinfo's font management macros allow customization of fonts used in
+the printed document.
+
+
+@menu
+* Introduction::
+* Font definition macros::
+* Font selection macros::
+* Font substitution macros::
+* Font collections::
+* Input encodings::
+* Font encodings::
+@end menu
+
+@node Introduction
+@section Introduction
+
+In this chapter we introduce the basic concepts of font management in
+Texinfo.
+
+@menu
+* Font features and attributes::
+* Current font attribute set::
+* Font substitution::
+@end menu
+
+@node Font features and attributes
+@subsection Font features and attributes
+
+@cindex font feature
+@cindex feature, of font
+@cindex font attribute
+@cindex attribute, of font
+Each font can be characterized by a number of @dfn{features}. For
+example, a font can be characterized by weight (boldness of glyph
+strokes), slant (inclination of glyph strokes), etc.
+
+Font @dfn{attribute} is a particular representation of a feature. For
+example, the ``weight'' feature can be represented by attributes
+``light'', ``medium'', ``semibold'', ``bold'', etc.; the ``slant''
+feature by attributes ``upright'', ``slanted'', ``italic'', etc.
+
+Most font features describe physical appearance of a font. However,
+two special features describe organizational aspects of fonts---font
+family and font encoding.
+
+@cindex font family
+@cindex family, of font
+A collection of related fonts is grouped into a @dfn{font family}.
+All fonts in a font family generally have the same or similar design,
+representing variations on that particular design. For example, a
+font family may include an upright font, an italic font and a bold
+upright font. Examples of font families: Computer Modern Roman,
+Times, Helvetica.
+
+@cindex font encoding
+@cindex encoding, of font
+@dfn{Font encoding} specifies the set and the order of characters
+represented within a font. Examples of font encodings: OT1 (Latin
+upper- and lower-case characters, arabic numerals and some additional
+glyphs), T1 (characters of Western-European scripts), T2A (characters
+of Cyrillic scripts). For a guide to @TeX{} font encodings, see
+@url{http://@/www.ctan.org/@/tex-archive/@/help/@/Catalogue/@/entries/@/encguide.html}.
+
+
+@node Current font attribute set
+@subsection Current font attribute set
+
+At font definition time, each font is associated with a set of
+attributes. Naturally, only one attribute can be specified per
+feature, but not every feature has to be represented.
+
+A font then can be selected by specifying a list of attributes. At
+all times, Texinfo maintains a @dfn{current font attribute set}.
+Texinfo provides macros to initialize this set, as well as to modify
+it by adding attributes or removing attributes corresponding to
+certain features. If a font definition is found which matches every
+attribute in the resulting attribute set, the corresponding font is
+selected.
+
+For example, let's assume the current font attribute set consists of
+the following attributes:
+
+@table @samp
+@item CMRoman
+``family'' feature
+@item OT1
+``encoding'' feature
+@item bold
+``weight'' feature
+@end table
+
+@noindent
+If now we instruct Texinfo to add attributes @samp{light} and
+@samp{italic} and to remove the @samp{encoding} feature, the font
+attribute set becomes:
+
+@table @samp
+@item CMRoman
+@item light
+replaces the @samp{bold} attribute of the ``weight'' feature
+@item italic
+``slant'' feature
+@end table
+
+@noindent
+Of course, in order for this font change specification to be
+successful, a font must be associated previously with such font
+attribute set.
+
+
+@node Font substitution
+@subsection Font substitution
+
+Sometimes it can be convenient to replace some attributes when a font
+with a certain set of attributes is requested. For example, a font
+family may contain slanted but not italic fonts. If we only define
+slanted fonts, all macros explicitly requesting italic font will fail
+when such font family is used. But we may decide that it is
+acceptable to use slanted fonts wherever italic fonts are being used.
+To achieve this, one solution is to create fake italic font
+definitions by duplicating definitions of slanted fonts and replacing
+the @samp{slanted} attribute with @samp{italic}. An alternative,
+simpler solution is to define font substitution, indicating that all
+requests for a font with the @samp{italic} attribute should be
+satisfied with a font with the @samp{slanted} attribute and all other
+font attributes unchanged.
+
+It is possible to specify more complex font substitutions which
+replace/add several attributes and/or remove attributes corresponding
+to certain features. All defined substitutions are applied in turn,
+starting with the current font attribute set, with the later
+substitutions performed on the result of the previous, so that it's
+possible to define chains of substitutions. Note that font
+substitution works with attribute sets; only the final attribute set
+is used to look up the corresponding font, so intermediate sets do not
+have to be associated with any font.
+
+Unlike font selection, font substitution is ``permissive'', that is,
+in order for a font substitution to be applied, its attribute set
+doesn't need to match the current font attribute set exactly, it can
+just be a subset of the font attribute set. For example, if a font
+substitution is defined to apply to the set of two attributes
+@samp{CMRoman} and @samp{OT1}, the substitution will also apply to any
+of the following attribute sets:
+
+@itemize
+@item @samp{CMRoman}, @samp{OT1}, @samp{upright};
+@item @samp{CMRoman}, @samp{OT1}, @samp{bold};
+@item @samp{CMRoman}, @samp{OT1}, @samp{upright}, @samp{bold};
+@end itemize
+
+@noindent
+but to none of the following:
+
+@itemize
+@item @samp{CMRoman};
+@item @samp{OT1};
+@item @samp{CMRoman}, @samp{upright};
+@item @samp{OT1}, @samp{upright}.
+@end itemize
+
+
+``Restrictive'' font substitutions, where attribute sets have to mach
+exactly, are (currently?) not supported.
+
+
+@node Other
+@subsection Other
+
+@dfn{Scaling factor} is an integer equal to magnification ratio
+times@tie{}1000.
+
+
+@node Font definition macros
+@section Font definition macros
+
+@findex newfontarrs
+Font attributes can be defined with the command
+
+@example
+@@newfontatrrs @var{feature} @var{attribute-list}
+@end example
+
+@noindent
+where @var{feature} is the font feature to associate the attributes
+with, @var{attribute-list} is a comma-separated list of one or more
+attributes to define. It is not an error to define an already defined
+attribute, as long as that attribute is associated with the same font
+feature as before.
+
+For example, the following command
+
+@example
+@@newfontattrs encoding OT1,OMS,OML,OMX
+@end example
+
+@noindent
+defines the classic @TeX{} font encodings. After the above
+definition, the following command will be valid:
+
+@example
+@@newfontattrs encoding OT1,T1
+@end example
+
+@noindent
+but the following command will generate an error (feature names are
+case-sensitive):
+
+@example
+@@newfontattrs Encoding OT1
+@end example
+
+@findex newfont
+A font can be defined with the command
+
+@example
+@@newfont @var{scale} @var{font} @var{size} @var{lskip}[,@var{reduced},@var{small},@var{smaller}] [@var{attr-list}]
+@end example
+
+@noindent
+Here optional parts are in square brackets. The arguments are as
+follows:
+
+@table @var
+@item scale
+Font's relative scaling factor (see below).
+
+@item font
+Font file name (e.g., @file{cmr10}).
+
+@item size
+Design size of the font (see below) specified as a @TeX{} dimension or
+a number (in which case @TeX{} points are assumed).
+
+@item lskip
+Recommended line skip scaling factor which will be multiplied by the
+selected font size to get the actual line skip.
+
+@item reduced
+Scaling factor for a reduced-size font (``one size smaller''), used
+for acronyms. Default is 909 (10/11).
+
+@item small
+Scaling factor for a small-size font (``two sizes smaller''), used
+for indices, footnotes, small examples, etc. Default is 818 (9/11).
+
+@item smaller
+Scaling factor for an even-smaller-size font (``three sizes
+smaller''), used for superscripts, subscripts, the @LaTeX{} logo, etc.
+Default is 727 (8/11).
+
+@item attr-list
+List of attributes to associate with the font. If omitted, attributes
+from the last @code{@@newfont} command are applied.
+@end table
+
+@i{This scheme doesn't provide for situation when we want different
+@var{reduced}, @var{small} and @var{smaller} settings for the same
+font for different size ranges.}
+
+
+@cindex scaling factor, of a font
+@cindex font scaling factor
+Different font families have different notions of font size. For
+example, Bera fonts at 10@dmn{pt} look much bigger than Computer
+Modern fonts at 10@dmn{pt}. When mixing fonts and font families,
+their sizes must be scaled to achieve visual uniformity. This is what
+the relative scaling factor (the first argument of @code{@@newfont})
+is for---it specifies the scaling factor which needs to be applied to
+a font to match a corresponding font from the Computer Modern
+collection of fonts (which are the default fonts of Texinfo).
+
+@i{Maybe it makes better sense to specify @var{scale} for the entire
+family and not for individual fonts. Not sure if fonts from the same
+family would ever need different scaling factors. One (hypothetical?)
+case I can think of is when a font family provides fonts at several
+design sizes, and those design sizes scale differently to the
+corresponding Computer Modern design sizes, so each design size has to
+be tweaked individually.}
+
+@cindex design size, of a font
+@cindex size, design, of a font
+@cindex font design size
+Each font has a @dfn{design size}, which is the size in which the
+designer intended the font to be displayed (the @var{size} argument of
+@code{@@newfont}). To produce a font in a size other than the design
+size, Texinfo can scale a font. Many font families provide fonts in
+only one design size, usually 10@dmn{pt}. When fonts are provided in
+several design sizes, it is best to define all the provided design
+sizes.
+
+For example, Computer Modern Roman font family provides five design
+sizes (7@dmn{pt}, 8@dmn{pt}, 9@dmn{pt}, 10@dmn{pt} and 12@dmn{pt}) for
+the italic medium-weight face, but only one design size (10@dmn{pt})
+for the upright caps and small caps face. The font encoding for both
+faces is @acronym{OT1}. Therefore, part of the definition of the
+CMRoman font family dealing with italic and caps and small caps faces
+might look like the following:
+
+@example
+@@newfontattrs family CMRoman
+@@newfontattrs encoding OT1
+@@newfontattrs slant upright,italic
+@@newfontattrs caps normalcaps,capssmallcaps
+
+@@newfont 1000 cmti7 7 1350 CMRoman,OT1,italic,normalcaps
+@@newfont 1000 cmti8 8 1300
+@@newfont 1000 cmti9 9 1250,1
+@@newfont 1000 cmti10 10 1200
+@@newfont 1000 cmti12 12 1150
+@@newfont 1000 cmcsc10 10 1200 CMRoman,OT1,upright,capssmallcaps
+@end example
+
+
+@node Font selection macros
+@section Font selection macros
+
+@findex setfont
+@cindex setting current attributes list
+@cindex current attributes list, setting
+@cindex setting a font
+@cindex selecting a font
+@cindex font, setting
+@cindex font, selecting
+The @code{@@setfont} command sets the current attribute list and then
+selects the font associated with that list:
+
+@example
+@@setfont@{@var{attribute-list}@}
+@end example
+
+@findex modfont
+If you don't want to specify all attributes but just want to add
+certain attributes to the current attribute list and/or remove
+attributes for certain features, use the command
+
+@example
+@@modfont@{@var{feature-list}@}@{@var{attribute-list}@}
+@end example
+
+@noindent
+Any attributes corresponding to features from @var{feature-list} will
+be removed from the current attribute list, attributes from
+@var{attribute-list} will be added to it, and the resulting attribute
+list will be used by Texinfo to select a font.
+
+
+@menu
+* Relative font scaling::
+@end menu
+
+@node Relative font scaling
+@subsection Relative font scaling
+
+@cindex scaling of fonts
+@findex fontbasescale
+By default, all fonts are scaled to match the Computer Modern fonts,
+and the Computer Modern fonts come out at their ``natural'' sizes.
+This happens when base font scaling factor is set to 1000, the
+relative scaling factor of the Computer Modern fonts. You can set a
+different base scaling factor using the command
+
+@example
+@@fontbasescale @var{scale}
+@end example
+
+@noindent
+If @var{scale} is omitted, the current font's relative scaling factor
+will be used.
+
+
+@node Font substitution macros
+@section Font substitution macros
+
+Each font substitution consists of three sets: filter (set of
+attributes), removed features (set of features) and added attributes
+(set of attributes). When selecting a font, Texinfo applies the list
+of defined substitutions to the current attribute list, and uses the
+resulting attribute list to selects a font.
+
+ examines each substitution in turn, applying
+those whose filter matches the current attribute list (i.e., those
+whose filter contains each attribute from the list) to the result of
+the previous substitutions on the current attribute list. The
+resulting attribute list as used to select a font.
+
+To add a substitution to the head of the substitution list, use the
+command
+
+@example
+@@fontsubstpre =@var{filter} -@var{removed-features} +@var{added-attributes}
+@end example
+
+The following command adds a substitution to the tail of the
+substitution list:
+@example
+@@fontsubstpost =@var{filter} -@var{removed-features} +@var{added-attributes}
+@end example
+
+
+@node Font collections
+@section Font collections
+
+@code{@@declarefontcollection}
+
+@code{@@fontcollection}
+
+
+@menu
+* Font styles::
+* Font style selection::
+* Font styles for document elements::
+@end menu
+
+@node Font styles
+@subsection Font styles
+
+@cindex font styles
+@cindex styles, fonts
+Font styles are a way to apply one of the defined font families to the
+text. It is possible to specify font styles for the various elements
+of a document individually, such as body text, page headings and
+footings, table of contents, indexes, and chapter, section, subsection
+and sub-subsection titles.
+
+@menu
+* Font style selection::
+* Font styles for document elements::
+@end menu
+
+
+@node Font style selection
+@subsection Font style selection
+
+Below are the styles defined by Texinfo, with the corresponding
+default meanings and commands which select them. All the style
+commands take a single argument in braces and typeset it according to
+font attributes specified for the style.
+
+@table @samp
+@findex serif
+@item serif
+serifed fonts (CMRoman), applied with @code{@@serif}.
+
+@findex sansserif
+@item sans
+sans serif fonts (CMSans), applied with @code{@@sansserif}.
+
+@findex t
+@item mono
+monospace fonts (CMMono), applied with @code{@@t}.
+
+@findex r
+@item default
+fonts used in absence of any style switches, and applied with
+@code{@@r} (CMRoman).
+
+@item math
+fonts used in math mode (CMMath), no explicit switches.
+@end table
+
+For example, the command
+
+@example
+@@sansserif@{text@}
+@end example
+
+@noindent
+typesets @samp{text} using the @samp{sans} font style (which results
+in a sans serif font by default).
+
+
+@node Font styles for document elements
+@subsection Font styles for document elements
+
+It is possible to customize each of the above styles separately for
+each element of the document. Texinfo associates styles with the
+following elements:
+
+@table @samp
+@item *
+Default, used for body text. Attributes from this `element' are also
+inherited by other elements, unless those elements redefine them.
+
+@item heading
+@itemx footing
+Page headings and footings.
+
+@item toc
+The table of contents.
+
+@item shorttoc
+The short table of contents.
+
+@item shorttocchapter
+Chapters in the short table of contents.
+
+@item index
+Indexes.
+
+@item indexinitials
+Initials in the index.
+
+@item title
+Document title.
+
+@item chapter
+@itemx section
+@itemx subsection
+@itemx subsubsection
+Chapter, section, subsection and sub-subsection titles.
+@end table
+
+@findex fontfamily
+To associate a font family with a particular style for a particular
+document element, use the following command:
+
+@example
+@@fontfamily @var{element} @var{style} @var{family}
+@end example
+
+@findex fontaxes
+To specify which font axes should be used, use the command
+
+@example
+@@fontaxes @var{element} @var{style} @var{axes}
+@end example
+
+@noindent
+where @var{axes} is a comma-separated list of axes, or a single
+@samp{.} if none.
+
+@findex fontsize
+@findex fontshape
+@findex fontweight
+The following commands will set font size, shape and weight to be used
+for a document element:
+
+@example
+@@fontsize @var{element} @var{point-size}
+@@fontshape @var{element} @var{shape}
+@@fontweight @var{element} @var{weight}
+@end example
+
+@findex unsetfonts
+Before you start defining font attributes for the styles, it might be
+a good idea to @code{@@unsetfonts}, which unsets all font attribute
+definitions except the defaults, which are set as follows:
+
+@example
+@@fontfamily * default CMRoman
+@@fontfamily * serif CMRoman
+@@fontfamily * sans CMSans
+@@fontfamily * mono CMMono
+@@fontfamily * math CMMath
+
+@@fontaxes * default .
+@@fontaxes * serif .
+@@fontaxes * sans .
+@@fontaxes * mono .
+@@fontaxes * math .
+
+@@fontsize * 11
+@@fontweight * m
+@@fontshape * n
+@end example
+
+@findex setfonts
+@findex resetfonts
+After you have finished specifying font attributes for the styles, you
+should activate them with @code{@@setfonts}. To revert to the default
+styles, call @code{@@resetfonts}.
+
+Below is a complete example of a document style specification.
+
+@example
+@@c Use Computer Modern fonts with no axes (the defaults).
+@@unsetfonts
+
+@@c The body text will be 12pt medium-weight upright font.
+@@fontsize * 12
+
+@@c Page headings are in a smaller italic font; footings are in
+@@c smaller upright.
+@@fontsize heading 10
+@@fontshape heading it
+@@fontsize footing 10
+
+@@c TOC is in the default face and smaller; indexes are in the default
+@@c face and even smaller.
+@@fontsize toc 11
+@@fontsize index 10
+
+@@c Font attributes for the title. We are not going to use @@serif,
+@@c @@sans, etc., so we don't care about non-default styles.
+@@fontfamily title * SomeFunkyFontFamily
+@@fontaxes title * of,pf
+@@fontsize title 20
+@@fontweight title bx
+@@fontshape title it
+
+@@c Use sans fonts for chapters, sections and subsections. We exchange
+@@c the meanings of @@sans and @@serif.
+
+@@fontfamily chapter * CMSans
+@@fontfamily chapter serif CMSans
+@@fontfamily chapter sans CMRoman
+@@fontfamily chapter math CMBrightMath
+@@fontsize chapter 17
+
+@@fontfamily section * CMSans
+@@fontfamily section serif CMSans
+@@fontfamily section sans CMRoman
+@@fontfamily section math CMBrightMath
+@@fontsize section 14
+
+@@fontfamily subsection * CMSans
+@@fontfamily subsection serif CMSans
+@@fontfamily subsection sans CMRoman
+@@fontfamily subsection math CMBrightMath
+@@fontsize subsection 12
+
+@@c Don't forget to activate the styles.
+@@setfonts
+@end example
+
+
+@node Input encodings
+@section Input encodings
+
+
+@node Font encodings
+@section Font encodings
+
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+
+@bye
+
+@c Local variables:
+@c compile-command: "texi2pdf texifont.txi && xpdf -remote key -raise -reload"
+@c End:
diff --git a/contrib/txipsfonts-bronger.tex b/contrib/txipsfonts-bronger.tex
new file mode 100644
index 0000000..8a85ada
--- /dev/null
+++ b/contrib/txipsfonts-bronger.tex
@@ -0,0 +1,6601 @@
+% pstexinfo.tex -- TeX macros to handle Texinfo files with
+% Postscript fonts modification
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2003-07-28.08-PS}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+%
+% Patch for Postscript fonts:
+% made 2003 by Torsten Bronger <bronger@users.sourceforge.net>
+%
+% This texinfo.tex file 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, or (at
+% your option) any later version.
+%
+% This pstexinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this pstexinfo.tex file; see the file COPYING. If not, write
+% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+% Boston, MA 02111-1307, USA.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+% ftp://tug.org/tex/texinfo.tex
+% (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org IF THEY REFER TO THE
+% ORIGINAL texinfo.tex PART OF THIS FILE. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+\message{Basics,}
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexnoindent=\noindent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% In some macros, we cannot use the `\? notation---the left quote is
+% in some cases the escape char.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\questChar = `\?
+\chardef\semiChar = `\;
+\chardef\spaceChar = `\ %
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{ap-pen-dix}
+\hyphenation{eshell}
+\hyphenation{mini-buf-fer mini-buf-fers}
+\hyphenation{time-stamp}
+\hyphenation{white-space}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\undefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines\maxdimen
+}%
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \escapechar = `\\ % use backslash in output files.
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingxxx.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 2\baselineskip
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \normalturnoffactive
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\next{#2}%
+ \begingroup
+ \obeylines
+ \catcode`\ =10
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argremovespace#1$ $\ArgTerm}
+% \argremovec might leave us with trailing space, though; e.g.,
+% @end itemize @c foo
+% Note that the argument cannot contain the TeX $, as its catcode is
+% changed to \other when Texinfo source is read.
+\def\argremovespace#1 $#2\ArgTerm{\finishparsearg#1$\ArgTerm}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it
+% just before passing the control to \next.
+% (But first, we have to spend the remaining $ or two.)
+\def\finishparsearg#1$#2\ArgTerm{\expandafter\next\expandafter{#1}}
+
+% \defparsearg\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\defparsearg#1{%
+ \expandafter \dodefparsearg \csname\string#1\endcsname #1%
+}
+\def\dodefparsearg#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+
+%% These are used to keep @begin/@end levels from running away
+%% Call \inENV within environments (after a \begingroup)
+\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
+\def\ENVcheck{%
+\ifENV\errmessage{Still within an environment; press RETURN to continue}
+\endgroup\fi} % This is not perfect, but it should reduce lossage
+
+% @end foo executes the definition of \Efoo.
+%
+\defparsearg\end{%
+ \expandafter\ifx\csname E#1\endcsname\relax
+ \badenderror{#1}%
+ \else
+ % Everything's ok; the right environment has been started.
+ \csname E#1\endcsname
+ \fi
+}
+
+\def\badenderror#1{%
+ \expandafter\ifx\csname#1\endcsname\relax
+ % There's no \foo, i.e., no ``environment'' foo.
+ \errhelp = \EMsimple
+ \errmessage{Undefined command `@end #1'}%
+ \else
+ \unmatchedenderror{#1}%
+ \fi
+}
+
+% There is an environment #1, but it hasn't been started. Give an error.
+%
+\def\unmatchedenderror#1{%
+ \errhelp = \EMsimple
+ \errmessage{This `@end #1' doesn't have a matching `@#1'}%
+}
+
+% Define the control sequence \E#1 to give an unmatched @end error.
+%
+\def\defineunmatchedend#1{%
+ \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux file.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ptexi
+ \else\ifx\temp\jmacro \j
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=3000 }
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=3000 }
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=3000 }
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\def\group{\begingroup
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ % The \vtop we start below produces a box with normal height and large
+ % depth; thus, TeX puts \baselineskip glue before it, and (when the
+ % next line of text is done) \lineskip glue after it. (See p.82 of
+ % the TeXbook.) Thus, space below is not quite equal to space
+ % above. But it's pretty close.
+ \def\Egroup{%
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \checkinserts
+ \endgroup % End the \group.
+ }%
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % We have to put a strut on the last line in case the @group is in
+ % the midst of an example, rather than completely enclosing it.
+ % Otherwise, the interline space between the last line of the group
+ % and the first line afterwards is too small. But we can't put the
+ % strut in \Egroup, since there it would be on a line by itself.
+ % Hence this just inserts a strut at the beginning of each line.
+ \everypar = {\strut}%
+ %
+ % Since we have a strut on every line, we don't need any of TeX's
+ % normal interline spacing.
+ \offinterlineskip
+ %
+ % OK, but now we have to do something about blank
+ % lines in the input in @example-like environments, which normally
+ % just turn into \lisppar, which will insert no space now that we've
+ % turned off the interline space. Simplest is to make them be an
+ % empty paragraph.
+ \ifx\par\lisppar
+ \edef\par{\leavevmode \par}%
+ %
+ % Reset ^^M's definition to new definition of \par.
+ \obeylines
+ \fi
+ %
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+% Old definition--didn't work.
+%\defparsearg\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\defparsearg\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break
+
+\let\br = \par
+
+% @dots{} output an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
+%
+\def\dots{%
+ \leavevmode
+ \hbox to 1.5em{%
+ \hskip 0pt plus 0.25fil minus 0.25fil
+ .\hss.\hss.%
+ \hskip 0pt plus 0.5fil minus 0.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \leavevmode
+ \hbox to 2em{%
+ \hskip 0pt plus 0.25fil minus 0.25fil
+ .\hss.\hss.\hss.%
+ \hskip 0pt plus 0.5fil minus 0.5fil
+ }%
+ \spacefactor=3000
+}
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\defparsearg\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\defparsearg\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @include file insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable
+ \def\temp{\input #1 }%
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\defparsearg\center{%
+ \ifhmode \hfil\break \fi
+ {%
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{\hfil \ignorespaces#1\unskip \hfil}%
+ }%
+ \ifhmode \break \fi
+}
+
+% @sp n outputs n lines of vertical space
+
+\defparsearg\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\defparsearg\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\defparsearg\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\newdimen\currentparindent
+%
+\def\insertword{insert}
+%
+\defparsearg\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode\underChar = \active
+ \gdef\mathunderscore{%
+ \catcode\underChar=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care. Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ $\finishmath
+}
+\def\finishmath#1{#1$\Etex}
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \iflinks
+ \readauxfile
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ % Just to be on the safe side, close the input stream before the \input.
+ \openin 1 texinfo.cnf
+ \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi
+ \closein1
+ \temp
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+\ifx\pdfoutput\undefined
+ \pdffalse
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\linkcolor = \relax
+ \let\pdfmakeoutlines = \relax
+\else
+ \pdftrue
+ \pdfoutput = 1
+ \input pdfcolor
+ \pdfcatalog{/PageMode /UseOutlines}%
+ \def\dopdfimage#1#2#3{%
+ \def\imagewidth{#2}%
+ \def\imageheight{#3}%
+ % without \immediate, pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifx\empty\imagewidth\else width \imagewidth \fi
+ \ifx\empty\imageheight\else height \imageheight \fi
+ \ifnum\pdftexversion<13
+ #1.pdf%
+ \else
+ {#1.pdf}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code in a section title
+ % aren't expanded.
+ \atdummies
+ \normalturnoffactive
+ \pdfdest name{#1} xyz%
+ }}
+ \def\pdfmkpgn#1{#1}
+ \let\linkcolor = \Blue % was Cyan, but that seems light?
+ \def\endlink{\Black\pdfendlink}
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node
+ % text, which might be empty if this toc entry had no
+ % corresponding node. #4 is the page number.
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worthwhile, since most documents are normally structured.
+ \def\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \openin 1 \jobname.toc
+ \ifeof 1\else\begingroup
+ \closein 1
+ % Thanh's hack / proper braces in bookmarks
+ \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+ \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+ %
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\numchapentry##1##2##3##4{\def\thischapnum{##2}}%
+ \def\numsecentry##1##2##3##4{%
+ \def\thissecnum{##2}%
+ \advancenumber{chap\thischapnum}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \def\thissubsecnum{##2}%
+ \advancenumber{sec\thissecnum}}%
+ \def\numsubsubsecentry##1##2##3##4{\advancenumber{subsec\thissubsecnum}}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \input \jobname.toc
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % Make special characters normal for writing to the pdf file.
+ \indexnofonts
+ \turnoffactive
+ \input \jobname.toc
+ \endgroup\fi
+ }
+ %
+ \def\makelinks #1,{%
+ \def\params{#1}\def\E{END}%
+ \ifx\params\E
+ \let\nextmakelinks=\relax
+ \else
+ \let\nextmakelinks=\makelinks
+ \ifnum\lnkcount>0,\fi
+ \picknum{#1}%
+ \startlink attr{/Border [0 0 0]}
+ goto name{\pdfmkpgn{\the\pgn}}%
+ \linkcolor #1%
+ \advance\lnkcount by 1%
+ \endlink
+ \fi
+ \nextmakelinks
+ }
+ \def\picknum#1{\expandafter\pn#1}
+ \def\pn#1{%
+ \def\p{#1}%
+ \ifx\p\lbrace
+ \let\nextpn=\ppn
+ \else
+ \let\nextpn=\ppnn
+ \def\first{#1}
+ \fi
+ \nextpn
+ }
+ \def\ppn#1{\pgn=#1\gobble}
+ \def\ppnn{\pgn=\first}
+ \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \ifx\p\space\else\addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \fi
+ \nextsp}
+ \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ \def\pdfurl#1{%
+ \begingroup
+ \normalturnoffactive\def\@{@}%
+ \makevalueexpandable
+ \leavevmode\Red
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ % #1
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \linkcolor #1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+% Font-change commands.
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf analogous to plain's \rm, etc.
+\newfam\sffam
+\def\sf{\fam=\sffam \tensf}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this one.
+\def\ttsl{\tenttsl}
+
+% Default leading.
+\newdimen\textleading \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix #3 is a scale factor
+\def\setrmfont#1#2#3{\font#1=\rmdefault#2 scaled #3}
+\def\setsffont#1#2#3{\font#1=\sfdefault#2 scaled #3}
+\def\setttfont#1#2#3{\font#1=\ttdefault#2 scaled #3}
+
+% Use Times/Helvetica/Courier as the default fonts.
+% To specify the font, you must define \??default
+% before you read in pstexinfo.tex.
+\ifx\rmdefault\undefined
+\def\rmdefault{ppl}
+\fi
+\ifx\sfdefault\undefined
+\def\sfdefault{phv}
+\fi
+\ifx\ttdefault\undefined
+\def\ttdefault{pcr}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r7t}
+\def\rmbshape{b7t} %where the normal face is bold
+\def\bfshape{b7t}
+\def\bxshape{b7t}
+\def\itshape{ri7t}
+\def\itbshape{bi7t}
+\def\slshape{ro7t}
+\def\slbshape{bo7t}
+\def\scshape{rc7t}
+\def\scbshape{bc7t}
+
+\newcount\mainmagstep
+\ifx\bigger\relax
+ % not really supported.
+ \mainmagstep=\magstep1
+ \setrmfont\textrm\rmshape{1200}
+ \setttfont\texttt\rmshape{1200}
+\else
+ \mainmagstep=\magstephalf
+ \setrmfont\textrm\rmshape{\mainmagstep}
+ \setttfont\texttt\rmshape{\mainmagstep}
+\fi
+% Instead of cmb10, you may want to use cmbx10.
+% cmbx10 is a prettier font on its own, but cmb10
+% looks better when embedded in a line with cmr10
+% (in Bob's opinion).
+\setrmfont\textbf\bfshape{\mainmagstep}
+\setrmfont\textit\itshape{\mainmagstep}
+\setrmfont\textsl\slshape{\mainmagstep}
+\setsffont\textsf\rmshape{\mainmagstep}
+\setrmfont\textsc\scshape{\mainmagstep}
+\setttfont\textttsl\slshape{\mainmagstep}
+\font\texti=zppler7m scaled \mainmagstep
+\font\textsy=zppler7y scaled \mainmagstep
+
+% A few fonts for @defun, etc.
+\setrmfont\defbf\bxshape{\magstep1} %was 1314
+\setttfont\deftt\rmshape{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\setrmfont\smallrm\rmshape{900}
+\setttfont\smalltt\rmshape{900}
+\setrmfont\smallbf\bfshape{900}
+\setrmfont\smallit\itshape{900}
+\setrmfont\smallsl\slshape{900}
+\setsffont\smallsf\rmshape{900}
+\setrmfont\smallsc\scshape{900}
+\setttfont\smallttsl\slshape{900}
+\font\smalli=zppler7m scaled 900
+\font\smallsy=zppler7y scaled 900
+
+% Fonts for small examples (8pt).
+\setrmfont\smallerrm\rmshape{800}
+\setttfont\smallertt\rmshape{800}
+\setrmfont\smallerbf\bfshape{800}
+\setrmfont\smallerit\itshape{800}
+\setrmfont\smallersl\slshape{800}
+\setsffont\smallersf\rmshape{800}
+\setrmfont\smallersc\scshape{800}
+\setttfont\smallerttsl\slshape{800}
+\font\smalleri=zppler7m scaled 800
+\font\smallersy=zppler7y scaled 800
+
+% Fonts for title page:
+\setrmfont\titlerm\rmbshape{\magstep4}
+\setrmfont\titleit\itbshape{\magstep4}
+\setrmfont\titlesl\slbshape{\magstep4}
+\setttfont\titlett\rmbshape{\magstep4}
+\setttfont\titlettsl\slshape{\magstep4}
+\setsffont\titlesf\rmbshape{\magstep4}
+\let\titlebf=\titlerm
+\setrmfont\titlesc\scbshape{\magstep4}
+\font\titlei=zppler7m scaled \magstep4
+\font\titlesy=zppler7y scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\setrmfont\chaprm\rmbshape{\magstep3}
+\setrmfont\chapit\itbshape{\magstep3}
+\setrmfont\chapsl\slbshape{\magstep3}
+\setttfont\chaptt\rmbshape{\magstep3}
+\setttfont\chapttsl\slshape{\magstep3}
+\setsffont\chapsf\rmbshape{\magstep3}
+\let\chapbf=\chaprm
+\setrmfont\chapsc\scbshape{\magstep3}
+\font\chapi=zppler7m scaled \magstep3
+\font\chapsy=zppler7y scaled \magstep3
+
+% Section fonts (14.4pt).
+\setrmfont\secrm\rmbshape{\magstep2}
+\setrmfont\secit\itbshape{\magstep2}
+\setrmfont\secsl\slbshape{\magstep2}
+\setttfont\sectt\rmbshape{\magstep2}
+\setttfont\secttsl\slshape{\magstep2}
+\setsffont\secsf\rmbshape{\magstep2}
+\let\secbf\secrm
+\setrmfont\secsc\scbshape{\magstep2}
+\font\seci=zppler7m scaled \magstep2
+\font\secsy=zppler7y scaled \magstep2
+
+% Subsection fonts (13.15pt).
+\setrmfont\ssecrm\rmbshape{1315}
+\setrmfont\ssecit\itbshape{1315}
+\setrmfont\ssecsl\slbshape{1315}
+\setttfont\ssectt\rmbshape{1315}
+\setttfont\ssecttsl\slshape{1315}
+\setsffont\ssecsf\rmbshape{1315}
+\let\ssecbf\ssecrm
+\setrmfont\ssecsc\scbshape{\magstep1}
+\font\sseci=zppler7m scaled 1315
+\font\ssecsy=zppler7y scaled 1315
+% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
+% but that is not a standard magnification.
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this so that font changes will continue to work
+% in math mode, where it is the current \fam that is relevant in most
+% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam
+% \tenbf}, for example. By redefining \tenbf, we obviate the need to
+% redefine \bf itself.
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf?
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \smallerfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+%
+% I wish we used A4 paper on this side of the Atlantic.
+%
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setrmfont\shortcontrm\rmshape{1200}
+\setrmfont\shortcontbf\bxshape{1200}
+\setrmfont\shortcontsl\slshape{1200}
+\setttfont\shortconttt\rmshape{1200}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+ \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\frenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ }
+\catcode`@=\other
+
+\def\t#1{%
+ {\tt \rawbackslash \frenchspacing #1}%
+ \null
+}
+\let\ttfont=\t
+\def\samp#1{`\tclose{#1}'\null}
+\setrmfont\keyrm\rmshape{800}
+\font\keysy=zppler7y scaled 900
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+ \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+ \vbox{\hrule\kern-0.4pt
+ \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+ \kern-0.4pt\hrule}%
+ \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \frenchspacing
+ #1%
+ }%
+ \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in \code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+ \catcode`\-=\active
+ \catcode`\_=\active
+ %
+ \global\def\code{\begingroup
+ \catcode`\-=\active \let-\codedash
+ \catcode`\_=\active \let_\codeunder
+ \codex
+ }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\defparsearg\kbdinputstyle{%
+ \def\arg{#1}%
+ \ifx\arg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\arg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\arg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle option `\arg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @url, @env, @command quotes seem unnecessary, so use \code.
+\let\url=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself. First (mandatory) arg is the url. Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \code{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @acronym downcases the argument and prints in smallcaps.
+% It would be nicer to go one point size down.
+\def\acronym#1{{\smallcaps \lowercase{#1}}}
+
+% @pounds{} is a sterling sign.
+\def\pounds{{\it\$}}
+
+% @registeredsymbol - R in a circle. For now, only works in text size;
+% we'd have to redo the font mechanism to change the \scriptstyle and
+% \scriptscriptstyle font sizes to make it look right in headings.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}%
+ }$%
+}
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\defparsearg\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\def\titlepage{%
+ \begingroup \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+ \let\tt=\authortt}
+
+\defparsearg\title{\leftline{\titlefonts\rm #1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt}
+
+\defparsearg\subtitle{{\subtitlefont \rightline{#1}}}
+
+% @author should come last, but may come many times.
+\defparsearg\author{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
+ {\authorfont \leftline{#1}}}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\defparsearg\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -\baselineskip
+ \global\advance\vsize by -\baselineskip
+}
+
+\defparsearg\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. (Unfortunately
+ % we can't prevent a possible page break at the following
+ % \baselineskip glue.) However, if what follows is an environment
+ % such as @example, there will be no \parskip glue; then
+ % the negative vskip we just would cause the example and the item to
+ % crash together. So we use this bizarre value of 10001 as a signal
+ % to \aboveenvbreak to insert \parskip glue after all.
+ % (Possibly there are other commands that could be followed by
+ % @example which need the same treatment, but not section titles; or
+ % maybe section titles are the only special case and they should be
+ % penalty 10001...)
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\def\table{%
+ \begingroup\inENV
+ \let\itemindex\gobble
+ \tablex
+}
+\def\ftable{%
+ \begingroup\inENV
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablex
+}
+\def\vtable{%
+ \begingroup\inENV
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablex
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak\endgroup}
+\let\Eftable\Etable
+\let\Evtable\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\defparsearg\itemize{%
+ \begingroup % ended by the @end itemize
+ \itemizey {#1}{\Eitemize}
+}
+
+\def\itemizey#1#2{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ \def#2{\endgraf\afterenvbreak\endgroup}%
+ \def\itemcontents{#1}%
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ \let\item=\itemizeitem
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\defparsearg\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ \begingroup % ended by the @end enumerate
+ %
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call itemizey, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \itemizey{#1.}\Eenumerate\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+% Definition of @item while inside @itemize.
+
+\def\itemizeitem{%
+\advance\itemno by 1
+{\let\par=\endgraf \smallbreak}%
+\ifhmode \errmessage{In hmode at itemizeitem}\fi
+{\parskip=0in \hskip 0pt
+\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
+\vadjust{\penalty 1200}}%
+\flushcr}
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the part of the @columnfraction before the decimal point, which
+% is presumably either 0 or the empty string (but we don't check, we
+% just throw it away). #2 is the decimal part, which we use as the
+% percent of \hsize for this column.
+\def\pickupwholefraction#1.#2 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{.#2\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+\def\headitem{\errmessage{@headitem outside of @multitable}}
+\def\tab{\errmessage{@tab outside of @multitable}}
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\defparsearg\multitable{\bgroup
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @headitem starts a heading row, which we typeset in bold.
+ % Assignments have to be global since we are inside the implicit group
+ % of an alignment entry.
+ \def\headitem{\crcrwithinserts \global\everytab={\bf}\the\everytab}%
+ %
+ % @item within a multitable starts a normal row, get rid of any bold.
+ \def\item{\crcrwithinserts \global\everytab={}}%
+ %
+ % A \tab used to include \hskip1sp. But then the space in a template
+ % line is not enough. That is bad. So let's go back to just & until
+ % we encounter the problem it was intended to solve again. --karl,
+ % nathan@acm.org, 20apr99.
+ \def\tab{&\the\everytab}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \def\Emultitable{%
+ \global\setpercentfalse
+ \crcrwithinserts
+ \egroup\egroup
+ }%
+ %
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % \everycr will reset column counter, \colcount, at the end of
+ % each line. Every column entry will cause \colcount to advance by one.
+ % The table preamble
+ % looks at the current \colcount to find the correct column width.
+ \everycr{\noalign{%
+ %
+ % \filbreak%% keeps underfull box messages off when table breaks over pages.
+ % Maybe so, but it also creates really weird page breaks when the table
+ % breaks over pages. Wouldn't \vfil be better? Wait until the problem
+ % manifests itself, so it can be fixed for real --karl.
+ \global\colcount=0\relax}}%
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup&\global\advance\colcount by 1\relax
+ \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively marking
+ % characters.
+ \noindent\ignorespaces##\unskip\multistrut}\cr
+}
+\def\crcrwithinserts{\crcr\noalign{\checkinserts}}
+
+\def\setmultitablespacing{% test to see if user has set \multitablelinespace.
+% If so, do nothing. If not, give it an appropriate dimension based on
+% current baselineskip.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+%% strut to put in table in case some entry doesn't have descenders,
+%% to keep lines equally spaced
+\let\multistrut = \strut
+\else
+%% FIXME: what is \box0 supposed to be?
+\gdef\multistrut{\vrule height\multitablelinespace depth\dp0
+width0pt\relax} \fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+% Prevent errors for section commands.
+% Used in @ignore and in failing conditionals.
+\def\ignoresections{%
+ \let\appendix=\relax
+ \let\appendixsec=\relax
+ \let\appendixsection=\relax
+ \let\appendixsubsec=\relax
+ \let\appendixsubsection=\relax
+ \let\appendixsubsubsec=\relax
+ \let\appendixsubsubsection=\relax
+ %\let\begin=\relax
+ %\let\bye=\relax
+ \let\centerchap=\relax
+ \let\chapter=\relax
+ \let\contents=\relax
+ \let\section=\relax
+ \let\smallbook=\relax
+ \let\subsec=\relax
+ \let\subsection=\relax
+ \let\subsubsec=\relax
+ \let\subsubsection=\relax
+ \let\titlepage=\relax
+ \let\top=\relax
+ \let\unnumbered=\relax
+ \let\unnumberedsec=\relax
+ \let\unnumberedsection=\relax
+ \let\unnumberedsubsec=\relax
+ \let\unnumberedsubsection=\relax
+ \let\unnumberedsubsubsec=\relax
+ \let\unnumberedsubsubsection=\relax
+}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescriptionword{documentdescription}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory = \comment
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \catcode\spaceChar = 10
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore {#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the string `ifinfo'.
+ %
+ % Define a command to find the next `@end #1', which must be on a line
+ % by itself.
+ \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \obeylines %
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+\def\enddoignore{\endgroup\ignorespaces}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\def\set{\parseargusing{\catcode`\-=\other \catcode`\_=\other}\setxxx}
+\def\setxxx#1{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\defparsearg\clear{\global\expandafter\let\csname SET#1\endcsname=\relax}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\- = \active \catcode`\_ = \active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\realdash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+\defparsearg\ifset{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \let\next=\ifsetfail
+ \else
+ \let\next=\ifsetsucceed
+ \fi
+ \next
+}
+\def\ifsetsucceed{\conditionalsucceed{ifset}}
+\def\ifsetfail{\doignore{ifset}}
+\defineunmatchedend{ifset}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+\defparsearg\ifclear{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \let\next=\ifclearsucceed
+ \else
+ \let\next=\ifclearfail
+ \fi
+ \next
+}
+\def\ifclearsucceed{\conditionalsucceed{ifclear}}
+\def\ifclearfail{\doignore{ifclear}}
+\defineunmatchedend{ifclear}
+
+% @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we
+% read the text following, through the first @end iftex (etc.). Make
+% `@end iftex' (etc.) valid only after an @iftex.
+%
+\def\iftex{\conditionalsucceed{iftex}}
+\def\ifnothtml{\conditionalsucceed{ifnothtml}}
+\def\ifnotinfo{\conditionalsucceed{ifnotinfo}}
+\def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}}
+\defineunmatchedend{iftex}
+\defineunmatchedend{ifnothtml}
+\defineunmatchedend{ifnotinfo}
+\defineunmatchedend{ifnotplaintext}
+
+% True conditional. Since \set globally defines its variables, we can
+% just start and end a group (to keep the @end definition undefined at
+% the outer level).
+%
+\def\conditionalsucceed#1{\begingroup
+ \expandafter\def\csname E#1\endcsname{\endgroup}%
+}
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within \newindex.
+{\catcode`\@=11
+\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname\donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ % Need these in case \tex is in effect and \{ is a \delimiter again.
+ % But can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters.
+ \let\{ = \mylbrace
+ \let\} = \myrbrace
+ %
+ % \definedummyword defines \#1 as \realbackslash #1\space, thus
+ % effectively preventing its expansion. This is used only for control
+ % words, not control letters, because the \space would be incorrect
+ % for control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword##1{%
+ \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}%
+ }%
+ \def\definedummyletter##1{%
+ \expandafter\def\csname ##1\endcsname{\realbackslash ##1}%
+ }%
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux file, @ is the escape character. So we want to redefine
+% everything using @ instead of \realbackslash. When everything uses
+% @, this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % (See comments in \indexdummies.)
+ \def\definedummyword##1{%
+ \expandafter\def\csname ##1\endcsname{@##1\space}%
+ }%
+ \def\definedummyletter##1{%
+ \expandafter\def\csname ##1\endcsname{@##1}%
+ }%
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% Called from \indexdummies and \atdummies. \definedummyword and
+% \definedummyletter must be defined first.
+%
+\def\commondummies{%
+ %
+ \normalturnoffactive
+ %
+ % Control letters and accents.
+ \definedummyletter{_}%
+ \definedummyletter{,}%
+ \definedummyletter{"}%
+ \definedummyletter{`}%
+ \definedummyletter{'}%
+ \definedummyletter{^}%
+ \definedummyletter{~}%
+ \definedummyletter{=}%
+ \definedummyword{u}%
+ \definedummyword{v}%
+ \definedummyword{H}%
+ \definedummyword{dotaccent}%
+ \definedummyword{ringaccent}%
+ \definedummyword{tieaccent}%
+ \definedummyword{ubaraccent}%
+ \definedummyword{udotaccent}%
+ \definedummyword{dotless}%
+ %
+ % Other non-English letters.
+ \definedummyword{AA}%
+ \definedummyword{AE}%
+ \definedummyword{L}%
+ \definedummyword{OE}%
+ \definedummyword{O}%
+ \definedummyword{aa}%
+ \definedummyword{ae}%
+ \definedummyword{l}%
+ \definedummyword{oe}%
+ \definedummyword{o}%
+ \definedummyword{ss}%
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword{bf}%
+ \definedummyword{gtr}%
+ \definedummyword{hat}%
+ \definedummyword{less}%
+ \definedummyword{sf}%
+ \definedummyword{sl}%
+ \definedummyword{tclose}%
+ \definedummyword{tt}%
+ %
+ % Texinfo font commands.
+ \definedummyword{b}%
+ \definedummyword{i}%
+ \definedummyword{r}%
+ \definedummyword{sc}%
+ \definedummyword{t}%
+ %
+ \definedummyword{TeX}%
+ \definedummyword{acronym}%
+ \definedummyword{cite}%
+ \definedummyword{code}%
+ \definedummyword{command}%
+ \definedummyword{dfn}%
+ \definedummyword{dots}%
+ \definedummyword{emph}%
+ \definedummyword{env}%
+ \definedummyword{file}%
+ \definedummyword{kbd}%
+ \definedummyword{key}%
+ \definedummyword{math}%
+ \definedummyword{option}%
+ \definedummyword{samp}%
+ \definedummyword{strong}%
+ \definedummyword{uref}%
+ \definedummyword{url}%
+ \definedummyword{var}%
+ \definedummyword{verb}%
+ \definedummyword{w}%
+ %
+ % Assorted special characters.
+ \definedummyword{bullet}%
+ \definedummyword{copyright}%
+ \definedummyword{registeredsymbol}%
+ \definedummyword{dots}%
+ \definedummyword{enddots}%
+ \definedummyword{equiv}%
+ \definedummyword{error}%
+ \definedummyword{expansion}%
+ \definedummyword{minus}%
+ \definedummyword{pounds}%
+ \definedummyword{point}%
+ \definedummyword{print}%
+ \definedummyword{result}%
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+ %
+ % Normal spaces, not active ones.
+ \unsepspaces
+ %
+ % No macro expansion.
+ \turnoffmacros
+}
+
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexdummytex{TeX}
+\def\indexdummydots{...}
+%
+\def\indexnofonts{%
+ \def\ { }%
+ \def\@{@}%
+ % how to handle braces?
+ \def\_{\normalunderscore}%
+ %
+ \let\,=\asis
+ \let\"=\asis
+ \let\`=\asis
+ \let\'=\asis
+ \let\^=\asis
+ \let\~=\asis
+ \let\==\asis
+ \let\u=\asis
+ \let\v=\asis
+ \let\H=\asis
+ \let\dotaccent=\asis
+ \let\ringaccent=\asis
+ \let\tieaccent=\asis
+ \let\ubaraccent=\asis
+ \let\udotaccent=\asis
+ \let\dotless=\asis
+ %
+ % Other non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\o{o}%
+ \def\ss{ss}%
+ \def\exclamdown{!}%
+ \def\questiondown{?}%
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ % Texinfo font commands.
+ \let\b=\asis
+ \let\i=\asis
+ \let\r=\asis
+ \let\sc=\asis
+ \let\t=\asis
+ %
+ \let\TeX=\indexdummytex
+ \let\acronym=\asis
+ \let\cite=\asis
+ \let\code=\asis
+ \let\command=\asis
+ \let\dfn=\asis
+ \let\dots=\indexdummydots
+ \let\emph=\asis
+ \let\env=\asis
+ \let\file=\asis
+ \let\kbd=\asis
+ \let\key=\asis
+ \let\math=\asis
+ \let\option=\asis
+ \let\samp=\asis
+ \let\strong=\asis
+ \let\uref=\asis
+ \let\url=\asis
+ \let\var=\asis
+ \let\verb=\asis
+ \let\w=\asis
+}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \ifvmode
+ \dosubindsanitize
+ \else
+ \dosubindwrite
+ \fi
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \escapechar=`\\
+ \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write will make \lastskip zero. The result is that sequences
+% like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+% ..., ready, GO:
+%
+\def\dosubindsanitize{%
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \skip0 = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \count255 = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\skip0 glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\skip0
+ \fi
+ %
+ \dosubindwrite
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % if \lastskip was zero, perhaps the last item was a
+ % penalty, and perhaps it was >=10000, e.g., a \nobreak.
+ % In that case, we want to re-insert the penalty; since we
+ % just inserted a non-discardable item, any following glue
+ % (such as a \parskip) would be a breakpoint. For example:
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\count255>9999 \nobreak \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\skip0
+ \fi
+}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\defparsearg\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\rawbackslashxx}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \penalty -300
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ \vskip .33\baselineskip plus .1\baselineskip
+ %
+ % Do our best not to break after the initial.
+ \nobreak
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straigtforward implementation would start like this:
+% \def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which set's active ``-''. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't what we really
+% want.
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#1}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.\ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise.
+% However, they are not reliable, because we don't use marks.
+\def\thischapter{}
+\def\thissection{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% Choose a numbered-heading macro
+% #1 is heading level if unmodified by @raisesections or @lowersections
+% #2 is text for heading
+\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \chapterzzz{#2}%
+ \or \seczzz{#2}%
+ \or \numberedsubseczzz{#2}%
+ \or \numberedsubsubseczzz{#2}%
+ \else
+ \ifnum \absseclevel<0 \chapterzzz{#2}%
+ \else \numberedsubsubseczzz{#2}%
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% like \numhead, but chooses appendix heading levels
+\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \appendixzzz{#2}%
+ \or \appendixsectionzzz{#2}%
+ \or \appendixsubseczzz{#2}%
+ \or \appendixsubsubseczzz{#2}%
+ \else
+ \ifnum \absseclevel<0 \appendixzzz{#2}%
+ \else \appendixsubsubseczzz{#2}%
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% like \numhead, but chooses numberless heading levels
+\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+ \ifcase\absseclevel
+ \unnumberedzzz{#2}%
+ \or \unnumberedseczzz{#2}%
+ \or \unnumberedsubseczzz{#2}%
+ \or \unnumberedsubsubseczzz{#2}%
+ \else
+ \ifnum \absseclevel<0 \unnumberedzzz{#2}%
+ \else \unnumberedsubsubseczzz{#2}%
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% @chapter, @appendix, @unnumbered.
+%
+\outer\defparsearg\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ \message{\putwordChapter\space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\defparsearg\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \def\appendixnum{\putwordAppendix\space \appendixletter}%
+ \message{\appendixnum}%
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\defparsearg\centerchap{{\unnumberedyyy{#1}}}
+
+\outer\defparsearg\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}\message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\defparsearg\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\defparsearg\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\defparsearg\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\defparsearg\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\defparsearg\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\defparsearg\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\defparsearg\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\defparsearg\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\defparsearg\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These are variants which are not "outer", so they can appear in @ifinfo.
+% Actually, they are now be obsolete; ordinary section commands should work.
+\def\infotop{\parsearg\unnumberedzzz}
+\def\infounnumbered{\parsearg\unnumberedzzz}
+\def\infounnumberedsec{\parsearg\unnumberedseczzz}
+\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
+\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
+
+\def\infoappendix{\parsearg\appendixzzz}
+\def\infoappendixsec{\parsearg\appendixseczzz}
+\def\infoappendixsubsec{\parsearg\appendixsubseczzz}
+\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
+
+\def\infochapter{\parsearg\chapterzzz}
+\def\infosection{\parsearg\sectionzzz}
+\def\infosubsection{\parsearg\subsectionzzz}
+\def\infosubsubsection{\parsearg\subsubsectionzzz}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+ \bigskip \par\penalty 200\relax
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\defparsearg\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\defparsearg\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\defparsearg\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+\def\CHAPFplain{%
+\global\let\chapmacro=\chfplain
+\global\let\centerchapmacro=\centerchfplain}
+
+% Normal chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chfplain#1#2#3{%
+ \pchapsepmacro
+ {%
+ \chapfonts \rm
+ %
+ % Have to define \thissection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \def\thischapter{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \xdef\thischapter{}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ % We don't substitute the actual chapter name into \thischapter
+ % because we don't want its macros evaluated now. And we don't
+ % use \thissection because that changes with each section.
+ %
+ \xdef\thischapter{\putwordAppendix{} \appendixletter:
+ \noexpand\thischaptername}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \xdef\thischapter{\putwordChapter{} \the\chapno:
+ \noexpand\thischaptername}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerchfplain#1{{%
+ \def\centerparametersmaybe{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+ }%
+ \chfplain{#1}{Ynothing}{}%
+}}
+
+\CHAPFplain % The default
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\nobreak
+}
+
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+
+\def\CHAPFopen{%
+\global\let\chapmacro=\chfopen
+\global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rm
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Only insert the space after the number if we have a section number.
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\thissection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \thissection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\thissection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\thissection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chfplain.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chfplain.
+ \donoderef{#3}%
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.)
+ \vskip-\parskip
+ %
+ % This \nobreak is purely so the last item on the list is a \penalty
+ % of 10000. This is so other code, for instance \parsebodycommon, can
+ % check for and avoid allowing breakpoints. Otherwise, it would
+ % insert a valid breakpoint between:
+ % @section sec-whatever
+ % @deffn def-whatever
+ \nobreak
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ \toks0 = {#2}%
+ \toks2 = \expandafter{\lastnode}%
+ \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}%
+ {\the\toks2}{\noexpand\folio}}}%
+ \temp
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \def\thischapter{}%
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
+ % We can't do this, because then an actual ^ in a section
+ % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97.
+ %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+
+% Normal (long) toc.
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \closein 1
+ \input \jobname.toc
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \pdfmakeoutlines
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \closein 1
+ \input \jobname.toc
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+\newdimen\tocindent \tocindent = 2pc
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\def\tex{\begingroup
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \escapechar=`\\
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+\let\Etex=\endgroup}
+
+% Define @lisp ... @end lisp.
+% @lisp does a \begingroup so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty>10000 \else \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\def\cartouche{%
+\begingroup\inENV
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing=\comment
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+\endgroup
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \inENV % This group ends at the end of the body
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ \parindent = 0pt
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ % @cartouche defines \nonarrowing to inhibit narrowing
+ % at next level down.
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \let\exdent=\nofillexdent
+ \let\nonarrowing=\relax
+ \fi
+}
+
+% Define the \E... control sequence only if we are inside the particular
+% environment, so the error checking in \end will work.
+%
+% To end an @example-like environment, we first end the paragraph (via
+% \afterenvbreak's vertical glue), and then the group. That way we keep
+% the zero \parskip that the environments set -- \parskip glue will be
+% inserted at the beginning of the next paragraph in the document, after
+% the environment.
+%
+\def\nonfillfinish{\afterenvbreak\endgroup}
+
+% @lisp: indented, narrowed, typewriter font.
+\def\lisp{\begingroup
+ \nonfillstart
+ \let\Elisp = \nonfillfinish
+ \tt
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+
+% @example: Same as @lisp.
+\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
+
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+\def\smalllisp{\begingroup
+ \def\Esmalllisp{\nonfillfinish\endgroup}%
+ \def\Esmallexample{\nonfillfinish\endgroup}%
+ \smallexamplefonts
+ \lisp
+}
+\let\smallexample = \smalllisp
+
+
+% @display: same as @lisp except keep current font.
+%
+\def\display{\begingroup
+ \nonfillstart
+ \let\Edisplay = \nonfillfinish
+ \gobble
+}
+%
+% @smalldisplay: @display plus smaller fonts.
+%
+\def\smalldisplay{\begingroup
+ \def\Esmalldisplay{\nonfillfinish\endgroup}%
+ \smallexamplefonts \rm
+ \display
+}
+
+% @format: same as @display except don't narrow margins.
+%
+\def\format{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eformat = \nonfillfinish
+ \gobble
+}
+%
+% @smallformat: @format plus smaller fonts.
+%
+\def\smallformat{\begingroup
+ \def\Esmallformat{\nonfillfinish\endgroup}%
+ \smallexamplefonts \rm
+ \format
+}
+
+% @flushleft (same as @format).
+%
+\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format}
+
+% @flushright.
+%
+\def\flushright{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushright = \nonfillfinish
+ \advance\leftskip by 0pt plus 1fill
+ \gobble
+}
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.
+%
+\def\quotation{%
+ \begingroup\inENV %This group ends at the end of the @quotation body
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ % We have retained a nonzero parskip for the environment, since we're
+ % doing normal filling. So to avoid extra space below the environment...
+ \def\Equotation{\parskip = 0pt \nonfillfinish}%
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \let\nonarrowing = \relax
+ \fi
+ \parsearg\quotationlabel
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+ \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \catcode`\`=\active
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen0=\wd0 % the width so far, or since the previous tab
+ \divide\dimen0 by\tabw
+ \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+ \advance\dimen0 by\tabw % advance to next multiple of \tabw
+ \wd0=\dimen0 \box0 \starttabbox
+ }%
+ }
+\endgroup
+\def\setupverbatim{%
+ \nonfillstart
+ \advance\leftskip by -\defbodyindent
+ % Easiest (and conventionally used) font for verbatim
+ \tt
+ \def\par{\leavevmode\egroup\box0\endgraf}%
+ \catcode`\`=\active
+ \tabexpand
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\def\verbatim{%
+ \let\Everbatim\nonfillfinish
+ \begingroup
+ \setupverbatim\doverbatim
+}
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ \begingroup
+ \makevalueexpandable
+ \setupverbatim
+ \input #1
+ \nonfillfinish % contains \endgroup
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later. Many commands won't be
+% allowed in this context, but that's ok.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\begingroup
+ % Define a command to swallow text until we reach `@end copying'.
+ % \ is the escape char in this texinfo.tex file, so it is the
+ % delimiter for the command; @ will be the escape char when we read
+ % it, but that doesn't matter.
+ \long\def\docopying##1\end copying{\gdef\copyingtext{##1}\enddocopying}%
+ %
+ % We must preserve ^^M's in the input file; see \insertcopying below.
+ \catcode`\^^M = \active
+ \docopying
+}
+
+% What we do to finish off the copying text.
+%
+\def\enddocopying{\endgroup\ignorespaces}
+
+% @insertcopying. Here we must play games with ^^M's. On the one hand,
+% we need them to delimit commands such as `@end quotation', so they
+% must be active. On the other hand, we certainly don't want every
+% end-of-line to be a \par, as would happen with the normal active
+% definition of ^^M. On the third hand, two ^^M's in a row should still
+% generate a \par.
+%
+% Our approach is to make ^^M insert a space and a penalty1 normally;
+% then it can also check if \lastpenalty=1. If it does, then manually
+% do \par.
+%
+% This messes up the normal definitions of @c[omment], so we redefine
+% it. Similarly for @ignore. (These commands are used in the gcc
+% manual for man page generation.)
+%
+% Seems pretty fragile, most line-oriented commands will presumably
+% fail, but for the limited use of getting the copying text (which
+% should be quite simple) inserted, we can hope it's ok.
+%
+{\catcode`\^^M=\active %
+\gdef\insertcopying{\begingroup %
+ \parindent = 0pt % looks wrong on title page
+ \def^^M{%
+ \ifnum \lastpenalty=1 %
+ \par %
+ \else %
+ \space \penalty 1 %
+ \fi %
+ }%
+ %
+ % Fix @c[omment] for catcode 13 ^^M's.
+ \def\c##1^^M{\ignorespaces}%
+ \let\comment = \c %
+ %
+ % Don't bother jumping through all the hoops that \doignore does, it
+ % would be very hard since the catcodes are already set.
+ \long\def\ignore##1\end ignore{\ignorespaces}%
+ %
+ \copyingtext %
+\endgroup}%
+}
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+% \startdefun \deffn
+% -- starts the processing of @deffn
+\def\startdefun#1{%
+ \begingroup\inENV
+ \def\thisenv{#1}%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check for penalty 10002 (inserted by
+ % \defargscommonending) instead of 10000, since the sectioning
+ % commands insert a \penalty10000, and we don't want to allow a break
+ % between a section heading and a defun.
+ \ifnum\lastpenalty=10002 \penalty2000 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+% \dodefunx \startdefun \deffn
+% -- converts \deffn expansion to \deffnx, omitting \startdefun.
+\def\dodefunx \startdefun #1{%
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \fi
+ %
+ % Check whether we are inside the corresponding @defun.
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \errmessage{\expandafter\string\temp x inside
+ \expandafter\noexpand\thisenv environment}%
+ \fi
+}
+
+% Without continued lines we'd just have:
+% \def\parsedefunline#1{\parseargusing\activeparens{\parsedefunlineX#1}}
+% \def\parsedefunlineX#1#2{\printdefunline #1#2\DefunTerm}
+% but with continuations, things are much more complicated.
+%
+\def\parsedefunline#1{%
+ \def\defunlinemacro{#1}% store \deffnheader (initially)
+ \parsedefunlineX
+}
+\def\parsedefunlineX{%
+ \parseargusing\activeparens\parsedefunlineY
+}
+\def\parsedefunlineY#1{%
+ % We have to prepend a token to prevent brace stripping;
+ % \defunlinemacro just comes handy.
+ \defunchkspace\defunlinemacro#1\DefunMid\ \DefunMid\DefunTerm
+}
+\def\defunchkspace#1\ \DefunMid#2\DefunTerm{%
+ \def\temp{#2}%
+ \ifx\temp\empty
+ % The line doesn't end with `@ '; in this case, #1 ends with \DefunMid.
+ \let\next\defunchktab
+ \else
+ % `@ ' was found and stripped.
+ \let\next\defunloop
+ \fi
+ \next#1\^^I\DefunMid\DefunTerm
+}
+\def\defunchktab#1\^^I\DefunMid#2\DefunTerm{%
+ \def\temp{#2}%
+ \ifx\temp\empty
+ % The line doesn't end with `@TAB', either.
+ \let\next\defunchkfinish
+ \else
+ % `@TAB' was found and stripped.
+ \let\next\defunloop
+ \fi
+ \next#1\^^I\DefunMid\DefunTerm
+}
+\def\defunloop#1\^^I\DefunMid\DefunTerm{%
+ % Expand the \defunlinemacro token at the beginning of #1.
+ \expandafter\def\expandafter\defunlinemacro
+ \expandafter{#1 }%
+ \parsedefunlineX
+}
+\def\defunchkfinish#1\DefunMid\^^I%\DefunMid\DefunTerm -- stays here
+{%
+ % #1 starts with \defunlinemacro, which is expanded and its expansion
+ % starts with eg. \deffnheader.
+ \expandafter\replaceeols #1\^^M%\DefunMid\DefunTerm -- stays here
+}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% The parameters start with \deffnheader token, so trere is no risk braces
+% could be stripped at #1. And we have a \DefunMid token just before
+% \DefunTerm, so we cannot loose braces at #2 either. Uff!
+%
+\def\replaceeols#1\^^M#2\DefunTerm{%
+ \stripDefunMid #2%
+ \ifx\temp\empty
+ % This \^^M is the terminating one.
+ \printdefunline #1\DefunTerm
+ \else
+ \replaceeolsX#1\^^M \^^M#2\DefunTerm
+ \fi
+}
+\def\replaceeolsX#1 \^^M{\replaceeolsY#1\^^M}
+\def\replaceeolsY#1\^^M#2\^^M{\replaceeols#1 }
+\def\stripDefunMid#1\DefunMid{\def\temp{#1}}
+
+% \printdefunline \deffnheader text\DefunTerm
+%
+\def\printdefunline#1\DefunTerm{%
+ \begingroup
+ % call \deffnheader:
+ #1 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty 10002 % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\endgroup\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \def#1{%
+ \startdefun#1%
+ \parsedefunline#3%
+ }%
+ % A tricky way to recycle the code defined above:
+ \def#2{\expandafter\dodefunx#1}%
+}
+
+% Untyped functions (@deffn, @defop):
+
+\makedefun{deffn} % category name args
+\def\deffnheader{\deffngeneral{}}
+
+\makedefun{defop} % category class name args
+\def\defopheader#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubin{fn}{xxx}{} is equivalent to \doind{fn}{xxx}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\ampdefunargs{#4\unskip}%
+}
+
+% Typed functions (@deftypefn, @deftypeop):
+
+\makedefun{deftypefn} % category type name args
+\def\deftypefnheader{\deftypefngeneral{}}
+
+\makedefun{deftypeop} % category class type name args
+\def\deftypeopheader#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\normaldefunargs{#5\unskip}%
+}
+
+% Typed variables (@deftypevr, @deftypecv):
+
+\makedefun{deftypevr}% category type var args
+\def\deftypevrheader{\deftypecvgeneral{}}
+
+\makedefun{deftypecv}% category class type var args
+\def\deftypecvheader#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\normaldefunargs{#5\unskip}%
+}
+
+% Untyped variables (@defvr, @defcv):
+\makedefun{defvr}% category var args
+\def\defvrheader#1 {\deftypevrheader{#1} {} }
+
+\makedefun{defcv}% category class var args
+\def\defcvheader#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+% Type (@deftp):
+\makedefun{deftp}% category name args
+\def\deftpheader#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\normaldefunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun} \def\defunheader{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac} \def\defmacheader{\deffnheader{\putwordDefmac} }
+\makedefun{defspec} \def\defspecheader{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}\def\deftypefunheader{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar} \def\defvarheader{\defvrheader{\putwordDefvar} }
+\makedefun{defopt} \def\defoptheader{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}\def\deftypevarheader{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod} \def\defmethodheader{\defopon\putwordMethodon}
+\makedefun{deftypemethod}\def\deftypemethodheader{\deftypeopon\putwordMethodon}
+\makedefun{defivar} \def\defivarheader{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}\def\deftypeivarheader{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % How we'll format the type name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape.
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ % (plain.tex says that \dimen1 should be used only as global.)
+ \parshape 2 0in \dimen0 \defargsindent \dimen2
+ %
+ % Put the type name to the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% return value type
+ \ifx\temp\empty\else \tclose{\temp} \fi
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% This expands the args, with & being treated magically.
+%
+\def\ampdefunargs{%
+ \magicamp
+ \normaldefunargs
+}
+
+% Print arguments in slanted typewriter, prevent hyphenation at `-' chars.
+%
+\def\normaldefunargs#1{%
+ % use sl by default (not ttsl), inconsistently with using tt for the
+ % name. This is because literal text is sometimes needed in the
+ % argument list (groff manual), and ttsl and tt are not very
+ % distinguishable.
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. Let's try @var for that.
+ \let\var=\ttslanted
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+\def\badparencount{%
+ \errmessage{Unbalanced parentheses in @def}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \errmessage{Unbalanced square braces in @def}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+ \newwrite\macscribble
+ \def\scanmacro#1{%
+ \begingroup \newlinechar`\^^M
+ % Undo catcode changes of \startcontents and \doprintindex
+ \catcode`\@=0 \catcode`\\=\other \escapechar=`\@
+ % Append \endinput to make sure that TeX does not see the ending newline.
+ \toks0={#1\endinput}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \let\xeatspaces\eatspaces
+ \input \jobname.tmp
+ \endgroup
+}
+\else
+\def\scanmacro#1{%
+\begingroup \newlinechar`\^^M
+% Undo catcode changes of \startcontents and \doprintindex
+\catcode`\@=0 \catcode`\\=\other \escapechar=`\@
+\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup}
+\fi
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+\def\macrolist{} % List of all defined macros in the form
+ % \do\macro1\do\macro2...
+
+% Utility routines.
+% Thisdoes \let #1 = #2, except with \csnames.
+\def\cslet#1#2{%
+\expandafter\expandafter
+\expandafter\let
+\expandafter\expandafter
+\csname#1\endcsname
+\csname#2\endcsname}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\macrobodyctxt{%
+ \catcode`\~=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\+=\other
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\@=\other
+ \catcode`\^^M=\other
+ \usembodybackslash}
+
+\def\macroargctxt{%
+ \catcode`\~=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\+=\other
+ \catcode`\@=\other
+ \catcode`\\=\other}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0%
+ \else
+ \expandafter\parsemargdef \argl;%
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ % Add the macroname to \macrolist
+ \toks0 = \expandafter{\macrolist\do}%
+ \xdef\macrolist{\the\toks0
+ \expandafter\noexpand\csname\the\macname\endcsname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\defparsearg\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\do\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx#1\relax
+ % remove this
+ \else
+ \noexpand\do \noexpand #1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+ \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1%
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \fi
+ \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \next}
+
+% We mant to disable all macros during \shipout so that they are not
+% expanded by \write.
+\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}%
+ \edef\next{\macrolist}\expandafter\endgroup\next}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.
+\defparsearg\node{\ENVcheck\nodexxx #1,\finishnodeparse}
+\def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), namely NAME-title (the corresponding @chapter/etc. name),
+% NAME-pg (the page number), and NAME-snt (section number and type).
+% Called from \donoderef and \anchor.
+%
+% We take care not to fully expand the title, since it may contain
+% arbitrary macros.
+%
+% Use \turnoffactive so that punctuation chars such as underscore
+% and backslash work in node names.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \turnoffactive
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\thissection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \writexrdef{pg}{\folio}% will be written later, during \shipout
+ }%
+ \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ \def\printedmanual{\ignorespaces #5}%
+ \def\printednodename{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual}%
+ \setbox0=\hbox{\printednodename}%
+ \ifdim \wd0 = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+ % Use the node name inside the square brackets.
+ \def\printednodename{\ignorespaces #1}%
+ \else
+ % Use the actual chapter/section title appear inside
+ % the square brackets. Use the real section title if we have it.
+ \ifdim \wd1 > 0pt
+ % It is in another manual, so we don't have it.
+ \def\printednodename{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printednodename{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printednodename{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifpdf
+ \leavevmode
+ \getfilename{#4}%
+ {\turnoffactive \otherbackslash
+ \ifnum\filenamelength>0
+ \startlink attr{/Border [0 0 0]}%
+ goto file{\the\filename.pdf} name{#1}%
+ \else
+ \startlink attr{/Border [0 0 0]}%
+ goto name{\pdfmkpgn{#1}}%
+ \fi
+ }%
+ \linkcolor
+ \fi
+ %
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive \otherbackslash
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via a macro.
+ \xrefprintnodename\printednodename
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+ \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since not square brackets don't work in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{\the\inputlineno:\space}
+\fi
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname X#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.
+%
+\def\xrdef#1{\expandafter\gdef\csname X#1\endcsname}
+
+% Read the last existing aux file, if any. No error if none exists.
+% Open the new one.
+%
+\def\readauxfile{\begingroup
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % Make the characters 128-255 be printing characters
+ {%
+ \count 1=128
+ \def\loop{%
+ \catcode\count 1=\other
+ \advance\count 1 by 1
+ \ifnum \count 1<256 \loop \fi
+ }%
+ }%
+ %
+ % Turn off \ as an escape so we do not lose on
+ % entries which were dumped with control sequences in their names.
+ % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^
+ % Reference to such entries still does not work the way one would wish,
+ % but at least they do not bomb out when the aux file is read in.
+ \catcode`\\=\other
+ %
+ % @ is our escape character in .aux files.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+ %
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \closein 1
+ \input \jobname.aux
+ \global\havexrefstrue
+ \fi
+ % Open the new aux file right away (otherwise the \immediate's in
+ % \setref cause spurious terminal output). TeX will close it
+ % automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacements works for both \insert\footins{xx} and
+% \insert\footins\bgroup xx\egroup, but it doesn't work for \insert27{xx}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1% \newbox cannot be pronounced, as it is outer
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins#1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ \closein 1
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\undefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \nobreak\bigskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \line\bgroup\hss
+ \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode \hss \egroup \bigbreak \fi % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LOC ... @end float for displayed figures, tables, etc.
+% We don't actually implement floating yet, we just plop the float "here".
+% But it seemed the best name for the future.
+%
+\def\float{\parsearg\parsefloat}
+\def\parsefloat#1{\dofloat #1,\finish}
+
+% #1 is the text label for this float, typically "Figure", "Table",
+% "Example", etc. #2 is optional and ignored; it will be for specifying
+% the positions allowed to float to (here, top, bottom).
+%
+\def\dofloat#1,#2\finish{\vtop\bgroup
+ % xx should we indent the whole thing? center it?
+ %
+ % allow @[short]caption now.
+ \let\thiscaption=\empty
+ \def\caption##1{\def\thiscaption{##1}}%
+ %
+ \let\thisshortcaption=\empty
+ \def\shortcaption##1{\def\thisshortcaption{##1}}%
+ %
+ \def\Efloat{%
+ \ifx\thiscaption\empty \else
+ \vskip.5\parskip
+ \thiscaption
+ \vskip\parskip
+ \fi
+ \egroup % end of \vtop
+ }%
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+\def\listoffloats{\parsearg\dolistoffloats}
+\def\dolistoffloats#1{%xx
+}
+
+% Default definitions.
+\def\caption{\errmessage{@caption while not in @float environment}}
+\def\shortcaption{\errmessage{@shortcaption while not in @float environment}}
+
+
+\message{localization,}
+% and i18n.
+
+% @documentlanguage is usually given very early, just after
+% @setfilename. If done too late, it may not override everything
+% properly. Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
+%
+\defparsearg\documentlanguage{%
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \let\temp = \relax
+ \else
+ \def\temp{\input txi-#1.tex }%
+ \fi
+ \temp
+ \endgroup
+}
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? In the current directory
+should work if nowhere else does.}
+
+
+% @documentencoding should change something in TeX eventually, most
+% likely, but for now just recognize it.
+\let\documentencoding = \comment
+
+
+% Page size parameters.
+%
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth; 3) voffset;
+% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8)
+% physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{46\baselineskip}{6in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.5 (or so) format.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{51\baselineskip}{160mm}
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\defparsearg\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in ttfont
+% where it can probably just be output, and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+\catcode`\@=0
+
+% \rawbackslashxx outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\rawbackslashxx=`\\
+
+% \rawbackslash defines an active \ to do \rawbackslashxx.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+{\catcode`\\=\active
+ @gdef@rawbackslash{@let\=@rawbackslashxx}
+ @gdef@otherbackslash{@let\=@realbackslash}
+}
+
+% \realbackslash is an actual character `\' with catcode other.
+{\catcode`\\=\other @gdef@realbackslash{\}}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\rawbackslashxx}}
+
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{%
+ @let"=@normaldoublequote
+ @let\=@realbackslash
+ @let~=@normaltilde
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let<=@normalless
+ @let>=@normalgreater
+ @let+=@normalplus
+ @let$=@normaldollar %$ font-lock fix
+ @unsepspaces
+}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'. (Thus, \ is not expandable when this is in
+% effect.)
+%
+@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also back turn on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+@c Set initial fonts.
+@textfonts
+@rm
+
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/contrib/txipsfonts-gildea.diff b/contrib/txipsfonts-gildea.diff
new file mode 100644
index 0000000..47aae3b
--- /dev/null
+++ b/contrib/txipsfonts-gildea.diff
@@ -0,0 +1,167 @@
+Date: Sun, 09 Jun 2002 00:40:14 -0400
+From: Stephen Gildea
+To: karl@freefriends.org (Karl Berry)
+cc: jgay@gnu.org
+Subject: Re: Texinfo fonts
+
+I used to like to use Adobe Times, Helvetica, and Courier because a
+major output format for us is PDF, and bitmapped fonts in a PDF file
+look ugly with acroread. I don't use this as much as I used to now that
+I can get Type 1 CM fonts.
+
+There are parts of this patch that look ugly, but it works for me.
+It would be great to see something like this support in the Texinfo
+distribution.
+
+ < Stephen
+
+*** texinfo.tex Mon Apr 19 17:13:00 1999
+--- ps_texinfo.tex Mon Apr 19 17:17:50 1999
+***************
+*** 58,69 ****
+ % It is possible to adapt texinfo.tex for other languages. You can get
+ % the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/.
+
+! \message{Loading texinfo [version \texinfoversion]:}
+
+ % If in a .fmt file, print the version number
+ % and turn on active characters that we couldn't do earlier because
+ % they might have appeared in the input file name.
+! \everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+ % Save some parts of plain tex whose names we will redefine.
+--- 58,69 ----
+ % It is possible to adapt texinfo.tex for other languages. You can get
+ % the existing language-specific files from ftp://ftp.gnu.org/gnu/texinfo/.
+
+! \message{Loading texinfo [version \texinfoversion ps]:}
+
+ % If in a .fmt file, print the version number
+ % and turn on active characters that we couldn't do earlier because
+ % they might have appeared in the input file name.
+! \everyjob{\message{[Texinfo version \texinfoversion ps]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+ % Save some parts of plain tex whose names we will redefine.
+***************
+*** 858,890 ****
+ \newcount\mainmagstep
+ \mainmagstep=\magstephalf
+
+ % Set the font macro #1 to the font named #2, adding on the
+ % specified font prefix (normally `cm').
+ % #3 is the font's design size, #4 is a scale factor
+! \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+ % Use cm as the default font prefix.
+ % To specify the font prefix, you must define \fontprefix
+ % before you read in texinfo.tex.
+ \ifx\fontprefix\undefined
+! \def\fontprefix{cm}
+ \fi
+ % Support font families that don't use the same naming scheme as CM.
+! \def\rmshape{r}
+! \def\rmbshape{bx} %where the normal face is bold
+! \def\bfshape{b}
+! \def\bxshape{bx}
+! \def\ttshape{tt}
+! \def\ttbshape{tt}
+! \def\ttslshape{sltt}
+! \def\itshape{ti}
+! \def\itbshape{bxti}
+! \def\slshape{sl}
+! \def\slbshape{bxsl}
+! \def\sfshape{ss}
+! \def\sfbshape{ss}
+! \def\scshape{csc}
+! \def\scbshape{csc}
+
+ \ifx\bigger\relax
+ \let\mainmagstep=\magstep1
+--- 858,916 ----
+ \newcount\mainmagstep
+ \mainmagstep=\magstephalf
+
++ % expand #1, a control sequence, without the leading escape char
++ \def\csstringname#1{\expandafter\csstrcdr\string#1;}
++ \def\csstrcdr#1#2;{#2}
++
++
+ % Set the font macro #1 to the font named #2, adding on the
+ % specified font prefix (normally `cm').
+ % #3 is the font's design size, #4 is a scale factor
+! \def\setfont#1#2#3#4{\dimen255=#3pt\divide\dimen255by1000
+! \multiply\dimen255by#4%
+! \global\expandafter\font\csname f/\csstringname#1\endcsname=\fontprefix#2\fontencoding\space at\dimen255
+! \global\def#1{\csname f/\csstringname#1\endcsname
+! \def\fcurshape{#2}%
+! \def\fcursize{#3}%
+! \def\fcurscale{#4}}}
+!
+
+ % Use cm as the default font prefix.
+ % To specify the font prefix, you must define \fontprefix
+ % before you read in texinfo.tex.
+ \ifx\fontprefix\undefined
+! \def\fontprefix{p}
+ \fi
+ % Support font families that don't use the same naming scheme as CM.
+! \def\fontencoding{7t}
+! \def\rmshape{tmr}
+! \def\rmbshape{tmb} %where the normal face is bold
+! \def\bfshape{tmb}
+! \def\bxshape{tmb}
+! \def\ttshape{crr}
+! \def\ttbshape{crb}
+! \def\ttslshape{crro}
+! \def\itshape{tmri}
+! \def\itbshape{tmbi}
+! \def\slshape{tmro}
+! \def\slbshape{tmbo}
+! \def\sfshape{hvr}
+! \def\sfbshape{hvb}
+! \def\scshape{tmrc}
+! \def\scbshape{tmbc}
+!
+! % the reason we save all the \fcur* stuff in \setfont
+! % is so we can do some nice symbols:
+!
+! \def\setcurtextsymbolfont{\def\fontencoding{8r}%
+! \expandafter\setfont
+! \csname\fontname\font/\fontencoding\endcsname
+! \fcurshape\fcursize\fcurscale
+! \csname\fontname\font/\fontencoding\endcsname}
+!
+! \def\copyright{{\setcurtextsymbolfont\char'251}}
+! \def\bullet{{\setcurtextsymbolfont\char'225}}
+!
+
+ \ifx\bigger\relax
+ \let\mainmagstep=\magstep1
+***************
+*** 1052,1059 ****
+ \textfonts
+
+ % Define these so they can be easily changed for other fonts.
+! \def\angleleft{$\langle$}
+! \def\angleright{$\rangle$}
+
+ % Count depth in font-changes, for error checks
+ \newcount\fontdepth \fontdepth=0
+--- 1078,1092 ----
+ \textfonts
+
+ % Define these so they can be easily changed for other fonts.
+!
+! \def\setcursymbolfont{\def\fontencoding{}%
+! \expandafter\setfont
+! \csname\fontname\font/syr\endcsname
+! {syr}\fcursize\fcurscale
+! \csname\fontname\font/syr\endcsname}
+!
+! \def\angleleft{{\setcursymbolfont\char'341}}
+! \def\angleright{{\setcursymbolfont\char'361}}
+
+ % Count depth in font-changes, for error checks
+ \newcount\fontdepth \fontdepth=0