diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-09-26 23:06:02 +0000 |
---|---|---|
committer | <> | 2015-02-03 11:56:22 +0000 |
commit | e0b511b834f3529395df67126a7314097c2cf97e (patch) | |
tree | 89945ae53183ab2acdc61659c8b0b3e57e4a1f3a /contrib | |
parent | 2d8ae7b161658c4a589172db0072fc99f76fa979 (diff) | |
download | texinfo-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')
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'} . "\"> </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 & GNU inquiries to +<a href="mailto:gnu@gnu.org"><gnu@gnu.org></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%%"><%%EMAIL%%></a>.</p> + +<p>Copyright © 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 Binary files differnew file mode 100644 index 0000000..1ef7d7f --- /dev/null +++ b/contrib/texifont/texifont.pdf 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\ }} + +\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 |