aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorJames <james.mckenzie@citrix.com>2012-11-16 10:41:01 +0000
committerJames <james.mckenzie@citrix.com>2012-11-16 10:41:01 +0000
commit041d1ea37802bf7178a31a53f96c26efa6b8fb7b (patch)
treec193e84ad1237f25a79d0f6a267722e44c73f56a /docs
downloadgrub-1.99-041d1ea37802bf7178a31a53f96c26efa6b8fb7b.tar.gz
grub-1.99-041d1ea37802bf7178a31a53f96c26efa6b8fb7b.tar.bz2
grub-1.99-041d1ea37802bf7178a31a53f96c26efa6b8fb7b.zip
fish
Diffstat (limited to 'docs')
-rw-r--r--docs/Makefile.am7
-rw-r--r--docs/Makefile.in1232
-rw-r--r--docs/fdl.texi452
-rw-r--r--docs/font_char_metrics.pngbin0 -> 16443 bytes
-rw-r--r--docs/font_char_metrics.txt1
-rw-r--r--docs/grub-dev.info2171
-rw-r--r--docs/grub-dev.texi1533
-rw-r--r--docs/grub.cfg75
-rw-r--r--docs/grub.info5228
-rw-r--r--docs/grub.texi4455
-rw-r--r--docs/man/grub-bin2h.h2m2
-rw-r--r--docs/man/grub-editenv.h2m5
-rw-r--r--docs/man/grub-emu.h2m6
-rw-r--r--docs/man/grub-fstest.h2m4
-rw-r--r--docs/man/grub-install.h2m7
-rw-r--r--docs/man/grub-macho2img.h2m4
-rw-r--r--docs/man/grub-menulst2cfg.h2m4
-rw-r--r--docs/man/grub-mkconfig.h2m4
-rw-r--r--docs/man/grub-mkdevicemap.h2m4
-rw-r--r--docs/man/grub-mkfont.h2m4
-rw-r--r--docs/man/grub-mkimage.h2m7
-rw-r--r--docs/man/grub-mklayout.h2m4
-rw-r--r--docs/man/grub-mknetdir.h2m4
-rw-r--r--docs/man/grub-mkpasswd-pbkdf2.h2m4
-rw-r--r--docs/man/grub-mkrelpath.h2m4
-rw-r--r--docs/man/grub-mkrescue.h2m4
-rw-r--r--docs/man/grub-ofpathname.h2m4
-rw-r--r--docs/man/grub-pe2elf.h2m4
-rw-r--r--docs/man/grub-probe.h2m4
-rw-r--r--docs/man/grub-reboot.h2m5
-rw-r--r--docs/man/grub-script-check.h2m4
-rw-r--r--docs/man/grub-set-default.h2m5
-rw-r--r--docs/man/grub-setup.h2m6
-rw-r--r--docs/mdate-sh205
-rw-r--r--docs/stamp-14
-rw-r--r--docs/stamp-vti4
-rw-r--r--docs/texinfo.tex8959
-rw-r--r--docs/version-dev.texi4
-rw-r--r--docs/version.texi4
39 files changed, 24437 insertions, 0 deletions
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644
index 0000000..6e15006
--- /dev/null
+++ b/docs/Makefile.am
@@ -0,0 +1,7 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+# AM_MAKEINFOFLAGS = --no-split --no-validate
+info_TEXINFOS = grub.texi grub-dev.texi
+grub_TEXINFOS = fdl.texi
+
+
diff --git a/docs/Makefile.in b/docs/Makefile.in
new file mode 100644
index 0000000..8ff9d06
--- /dev/null
+++ b/docs/Makefile.in
@@ -0,0 +1,1232 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# 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.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = docs
+DIST_COMMON = $(grub_TEXINFOS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/stamp-1 $(srcdir)/stamp-vti \
+ $(srcdir)/version-dev.texi $(srcdir)/version.texi mdate-sh \
+ texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
+ $(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/argp.m4 \
+ $(top_srcdir)/m4/asm-underscore.m4 $(top_srcdir)/m4/btowc.m4 \
+ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/dirname.m4 \
+ $(top_srcdir)/m4/dos.m4 $(top_srcdir)/m4/double-slash-root.m4 \
+ $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/error.m4 \
+ $(top_srcdir)/m4/extensions.m4 $(top_srcdir)/m4/fcntl-o.m4 \
+ $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/fnmatch.m4 \
+ $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getline.m4 \
+ $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/include_next.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax_t.m4 \
+ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/langinfo_h.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/localcharset.m4 $(top_srcdir)/m4/locale-fr.m4 \
+ $(top_srcdir)/m4/locale-ja.m4 $(top_srcdir)/m4/locale-zh.m4 \
+ $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/malloc.m4 \
+ $(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbsinit.m4 \
+ $(top_srcdir)/m4/mbsrtowcs.m4 $(top_srcdir)/m4/mbstate_t.m4 \
+ $(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/mempcpy.m4 \
+ $(top_srcdir)/m4/mmap-anon.m4 $(top_srcdir)/m4/multiarch.m4 \
+ $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/printf.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/rawmemchr.m4 \
+ $(top_srcdir)/m4/realloc.m4 $(top_srcdir)/m4/regex.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/sleep.m4 \
+ $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stdbool.m4 \
+ $(top_srcdir)/m4/stddef_h.m4 $(top_srcdir)/m4/stdint.m4 \
+ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/stdio_h.m4 \
+ $(top_srcdir)/m4/stdlib_h.m4 $(top_srcdir)/m4/strcase.m4 \
+ $(top_srcdir)/m4/strchrnul.m4 $(top_srcdir)/m4/strerror.m4 \
+ $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strings_h.m4 \
+ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \
+ $(top_srcdir)/m4/sys_wait_h.m4 $(top_srcdir)/m4/sysexits.m4 \
+ $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/vasnprintf.m4 \
+ $(top_srcdir)/m4/vsnprintf.m4 $(top_srcdir)/m4/warn-on-use.m4 \
+ $(top_srcdir)/m4/wchar_h.m4 $(top_srcdir)/m4/wchar_t.m4 \
+ $(top_srcdir)/m4/wcrtomb.m4 $(top_srcdir)/m4/wctype_h.m4 \
+ $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/xsize.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config-util.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/grub.info $(srcdir)/grub-dev.info
+TEXINFO_TEX = $(top_srcdir)/build-aux/texinfo.tex
+am__TEXINFO_TEX_DIR = $(top_srcdir)/build-aux
+DVIS = grub.dvi grub-dev.dvi
+PDFS = grub.pdf grub-dev.pdf
+PSS = grub.ps grub-dev.ps
+HTMLS = grub.html grub-dev.html
+TEXINFOS = grub.texi grub-dev.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__installdirs = "$(DESTDIR)$(infodir)"
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADDR32 = @ADDR32@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+BSS_START_SYMBOL = @BSS_START_SYMBOL@
+BUILD_CC = @BUILD_CC@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMP = @CMP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATA32 = @DATA32@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+END_SYMBOL = @END_SYMBOL@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
+EXEEXT = @EXEEXT@
+FLOAT_H = @FLOAT_H@
+FNMATCH_H = @FNMATCH_H@
+FONT_SOURCE = @FONT_SOURCE@
+FREETYPE = @FREETYPE@
+GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+GNULIB_FOPEN = @GNULIB_FOPEN@
+GNULIB_FPRINTF = @GNULIB_FPRINTF@
+GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
+GNULIB_FPURGE = @GNULIB_FPURGE@
+GNULIB_FPUTC = @GNULIB_FPUTC@
+GNULIB_FPUTS = @GNULIB_FPUTS@
+GNULIB_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDELIM = @GNULIB_GETDELIM@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLINE = @GNULIB_GETLINE@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
+GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
+GNULIB_MBSCHR = @GNULIB_MBSCHR@
+GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSLEN = @GNULIB_MBSLEN@
+GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
+GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
+GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
+GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MBSSEP = @GNULIB_MBSSEP@
+GNULIB_MBSSPN = @GNULIB_MBSSPN@
+GNULIB_MBSSTR = @GNULIB_MBSSTR@
+GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
+GNULIB_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_REMOVE = @GNULIB_REMOVE@
+GNULIB_RENAME = @GNULIB_RENAME@
+GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
+GNULIB_STPCPY = @GNULIB_STPCPY@
+GNULIB_STPNCPY = @GNULIB_STPNCPY@
+GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
+GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
+GNULIB_STRDUP = @GNULIB_STRDUP@
+GNULIB_STRERROR = @GNULIB_STRERROR@
+GNULIB_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+GRUB_BOOT_MACHINE_LINK_ADDR = @GRUB_BOOT_MACHINE_LINK_ADDR@
+HAVE_ASM_USCORE = @HAVE_ASM_USCORE@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
+HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
+HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
+HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
+HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@
+HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_GETDOMAINNAME = @HAVE_GETDOMAINNAME@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MEMCHR = @HAVE_MEMCHR@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASECMP = @HAVE_STRCASECMP@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYSEXITS_H = @HAVE_SYSEXITS_H@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_TTYNAME_R = @HAVE_TTYNAME_R@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSETENV = @HAVE_UNSETENV@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+HELP2MAN = @HELP2MAN@
+HOST_CC = @HOST_CC@
+HOST_CCASFLAGS = @HOST_CCASFLAGS@
+HOST_CFLAGS = @HOST_CFLAGS@
+HOST_CPPFLAGS = @HOST_CPPFLAGS@
+HOST_LDFLAGS = @HOST_LDFLAGS@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBCURSES = @LIBCURSES@
+LIBDEVMAPPER = @LIBDEVMAPPER@
+LIBGEOM = @LIBGEOM@
+LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@
+LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBLZMA = @LIBLZMA@
+LIBNVPAIR = @LIBNVPAIR@
+LIBOBJS = @LIBOBJS@
+LIBPCIACCESS = @LIBPCIACCESS@
+LIBS = @LIBS@
+LIBSDL = @LIBSDL@
+LIBUSB = @LIBUSB@
+LIBUTIL = @LIBUTIL@
+LIBZFS = @LIBZFS@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NEED_ENABLE_EXECUTE_STACK = @NEED_ENABLE_EXECUTE_STACK@
+NEED_REGISTER_FRAME_INFO = @NEED_REGISTER_FRAME_INFO@
+NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYSEXITS_H = @NEXT_AS_FIRST_DIRECTIVE_SYSEXITS_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRINGS_H = @NEXT_STRINGS_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYSEXITS_H = @NEXT_SYSEXITS_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+OBJCONV = @OBJCONV@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+SYSEXITS_H = @SYSEXITS_H@
+TARGET_APPLE_CC = @TARGET_APPLE_CC@
+TARGET_CC = @TARGET_CC@
+TARGET_CCAS = @TARGET_CCAS@
+TARGET_CCASFLAGS = @TARGET_CCASFLAGS@
+TARGET_CFLAGS = @TARGET_CFLAGS@
+TARGET_CPP = @TARGET_CPP@
+TARGET_CPPFLAGS = @TARGET_CPPFLAGS@
+TARGET_IMG_BASE_LDOPT = @TARGET_IMG_BASE_LDOPT@
+TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@
+TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@
+TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@
+TARGET_LDFLAGS = @TARGET_LDFLAGS@
+TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@
+TARGET_OBJ2ELF = @TARGET_OBJ2ELF@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+USE_APPLE_CC_FIXES = @USE_APPLE_CC_FIXES@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_TARGET_CC = @ac_ct_TARGET_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+bootdirname = @bootdirname@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_efiemu = @enable_efiemu@
+enable_grub_emu_pci = @enable_grub_emu_pci@
+enable_grub_emu_sdl = @enable_grub_emu_sdl@
+enable_grub_emu_usb = @enable_grub_emu_usb@
+enable_grub_mkfont = @enable_grub_mkfont@
+exec_prefix = @exec_prefix@
+freetype_cflags = @freetype_cflags@
+freetype_libs = @freetype_libs@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+grubdirname = @grubdirname@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_kernel = @host_kernel@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkglibrootdir = @pkglibrootdir@
+platform = @platform@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = subdir-objects
+
+# AM_MAKEINFOFLAGS = --no-split --no-validate
+info_TEXINFOS = grub.texi grub-dev.texi
+grub_TEXINFOS = fdl.texi
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texi
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu docs/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+.texi.info:
+ restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ $(am__cd) $(srcdir); \
+ else \
+ rc=$$?; \
+ $(am__cd) $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $<
+
+.texi.pdf:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $<
+
+.texi.html:
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+$(srcdir)/grub.info: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+grub.dvi: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+grub.pdf: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+grub.html: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+$(srcdir)/version.texi: $(srcdir)/stamp-vti
+$(srcdir)/stamp-vti: grub.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./grub.texi || dir=$(srcdir); \
+ set `$(SHELL) $(top_srcdir)/build-aux/mdate-sh $$dir/grub.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > vti.tmp
+ @cmp -s vti.tmp $(srcdir)/version.texi \
+ || (echo "Updating $(srcdir)/version.texi"; \
+ cp vti.tmp $(srcdir)/version.texi)
+ -@rm -f vti.tmp
+ @cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+ -rm -f vti.tmp
+
+maintainer-clean-vti:
+ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+$(srcdir)/grub-dev.info: grub-dev.texi $(srcdir)/version-dev.texi
+grub-dev.dvi: grub-dev.texi $(srcdir)/version-dev.texi
+grub-dev.pdf: grub-dev.texi $(srcdir)/version-dev.texi
+grub-dev.html: grub-dev.texi $(srcdir)/version-dev.texi
+$(srcdir)/version-dev.texi: $(srcdir)/stamp-1
+$(srcdir)/stamp-1: grub-dev.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./grub-dev.texi || dir=$(srcdir); \
+ set `$(SHELL) $(top_srcdir)/build-aux/mdate-sh $$dir/grub-dev.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > 1.tmp
+ @cmp -s 1.tmp $(srcdir)/version-dev.texi \
+ || (echo "Updating $(srcdir)/version-dev.texi"; \
+ cp 1.tmp $(srcdir)/version-dev.texi)
+ -@rm -f 1.tmp
+ @cp $(srcdir)/version-dev.texi $@
+
+mostlyclean-1:
+ -rm -f 1.tmp
+
+maintainer-clean-1:
+ -rm -f $(srcdir)/stamp-1 $(srcdir)/version-dev.texi
+.dvi.ps:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && \
+ (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf grub.aux grub.cp grub.cps grub.fn grub.ky grub.log grub.pg grub.tmp \
+ grub.toc grub.tp grub.vr grub-dev.aux grub-dev.cp \
+ grub-dev.cps grub-dev.fn grub-dev.ky grub-dev.log \
+ grub-dev.pg grub-dev.tmp grub-dev.toc grub-dev.tp \
+ grub-dev.vr
+
+clean-aminfo:
+ -test -z "grub.dvi grub.pdf grub.ps grub.html grub-dev.dvi grub-dev.pdf \
+ grub-dev.ps grub-dev.html" \
+ || rm -rf grub.dvi grub.pdf grub.ps grub.html grub-dev.dvi grub-dev.pdf \
+ grub-dev.ps grub-dev.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: check-am
+all-am: Makefile $(INFO_DEPS)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-aminfo clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)"
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ if test -d "$$d$$p"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d$$p"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)"
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)"
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-1 \
+ maintainer-clean-aminfo maintainer-clean-generic \
+ maintainer-clean-vti
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-1 mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-vti
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ dist-info distclean distclean-generic distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-1 maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti mostlyclean \
+ mostlyclean-1 mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-vti pdf pdf-am ps ps-am uninstall uninstall-am \
+ uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/docs/fdl.texi b/docs/fdl.texi
new file mode 100644
index 0000000..fe78df8
--- /dev/null
+++ b/docs/fdl.texi
@@ -0,0 +1,452 @@
+
+@node GNU Free Documentation License
+@appendixsec GNU Free Documentation License
+
+@cindex FDL, GNU Free Documentation License
+@center Version 1.2, November 2002
+
+@display
+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
+format, @acronym{SGML} or @acronym{XML} using a publicly available
+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
+PostScript or @acronym{PDF} designed for human modification. Examples
+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
+@acronym{JPG}. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, @acronym{SGML} or
+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
+not generally available, and the machine-generated @acronym{HTML},
+PostScript or @acronym{PDF} produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided for under this License. Any other attempt to
+copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License. However,
+parties who have received copies, or rights, from you under this
+License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.
+@end enumerate
+
+@page
+@appendixsubsec ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with...Texts.'' line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
+
diff --git a/docs/font_char_metrics.png b/docs/font_char_metrics.png
new file mode 100644
index 0000000..8d10d1f
--- /dev/null
+++ b/docs/font_char_metrics.png
Binary files differ
diff --git a/docs/font_char_metrics.txt b/docs/font_char_metrics.txt
new file mode 100644
index 0000000..92f1371
--- /dev/null
+++ b/docs/font_char_metrics.txt
@@ -0,0 +1 @@
+Please fill this in.
diff --git a/docs/grub-dev.info b/docs/grub-dev.info
new file mode 100644
index 0000000..0510b36
--- /dev/null
+++ b/docs/grub-dev.info
@@ -0,0 +1,2171 @@
+This is /home/phcoder/grub2/bzr/grub-1.99/docs/grub-dev.info, produced
+by makeinfo version 4.13 from
+/home/phcoder/grub2/bzr/grub-1.99/docs/grub-dev.texi.
+
+This developer manual is for GNU GRUB (version 1.99, 13 April 2011).
+
+ Copyright (C) 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011
+Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.2 or any later version published by the Free Software
+ Foundation; with no Invariant Sections.
+
+INFO-DIR-SECTION Kernel
+START-INFO-DIR-ENTRY
+* grub-dev: (grub-dev). The GRand Unified Bootloader Dev
+END-INFO-DIR-ENTRY
+
+
+File: grub-dev.info, Node: Top, Next: Getting the source code, Up: (dir)
+
+GNU GRUB developer manual
+*************************
+
+This is the developer documentation of GNU GRUB, the GRand Unified
+Bootloader, a flexible and powerful boot loader program for a wide
+range of architectures.
+
+ This edition documents version 1.99.
+
+ This developer manual is for GNU GRUB (version 1.99, 13 April 2011).
+
+ Copyright (C) 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011
+Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.2 or any later version published by the Free Software
+ Foundation; with no Invariant Sections.
+
+* Menu:
+
+* Getting the source code::
+* Finding your way around::
+* Coding style::
+* Contributing Changes::
+* Error Handling::
+* CIA::
+* BIOS port memory map::
+* Video Subsystem::
+* PFF2 Font File Format::
+* Graphical Menu Software Design::
+* Copying This Manual:: Copying This Manual
+* Index::
+
+
+File: grub-dev.info, Node: Getting the source code, Next: Finding your way around, Prev: Top, Up: Top
+
+1 Getting the source code
+*************************
+
+GRUB is maintained using the Bazaar revision control system
+(http://bazaar-vcs.org/). To fetch the primary development branch:
+
+ bzr get http://bzr.savannah.gnu.org/r/grub/trunk/grub
+
+ The GRUB developers maintain several other branches with work in
+progress. Of these, the most interesting is the experimental branch,
+which is a staging area for new code which we expect to eventually
+merge into trunk but which is not yet ready:
+
+ bzr get http://bzr.savannah.gnu.org/r/grub/branches/experimental
+
+ Once you have used `bzr get' to fetch an initial copy of a branch,
+you can use `bzr pull' to keep it up to date. If you have modified your
+local version, you may need to resolve conflicts when pulling.
+
+
+File: grub-dev.info, Node: Coding style, Next: Contributing Changes, Prev: Finding your way around, Up: Top
+
+2 Coding style
+**************
+
+Basically we follow the GNU Coding Standards
+(http://www.gnu.org/prep/standards_toc.html). We define additional
+conventions for GRUB here.
+
+* Menu:
+
+* Naming Conventions::
+* Functions::
+* Variables::
+* Types::
+* Macros::
+* Comments::
+* Multi-Line Comments::
+
+
+File: grub-dev.info, Node: Naming Conventions, Next: Functions, Up: Coding style
+
+2.1 Naming Conventions
+======================
+
+All global symbols (i.e. functions, variables, types, and macros) must
+have the prefix grub_ or GRUB_. The all capital form is used only by
+macros.
+
+
+File: grub-dev.info, Node: Functions, Next: Variables, Prev: Naming Conventions, Up: Coding style
+
+2.2 Functions
+=============
+
+If a function is global, its name must be prefixed with grub_ and must
+consist of only small letters. If the function belongs to a specific
+function module, the name must also be prefixed with the module name.
+For example, if a function is for file systems, its name is prefixed
+with grub_fs_. If a function is for FAT file system but not for all
+file systems, its name is prefixed with grub_fs_fat_. The hierarchy is
+noted this way.
+
+ After a prefix, a function name must start with a verb (such as get
+or is). It must not be a noun. Some kind of abbreviation is permitted,
+as long as it wouldn't make code less readable (e.g. init).
+
+ If a function is local, its name may not start with any prefix. It
+must start with a verb.
+
+
+File: grub-dev.info, Node: Variables, Next: Types, Prev: Functions, Up: Coding style
+
+2.3 Variables
+=============
+
+The rule is mostly the same as functions, as noted above. If a variable
+is global, its name must be prefixed with grub_ and must consist of
+only small letters. If the variable belongs to a specific function
+module, the name must also be prefixed with the module name. For
+example, if a function is for dynamic loading, its name is prefixed
+with grub_dl_. If a variable is for ELF but not for all dynamic loading
+systems, its name is prefixed with grub_dl_elf_.
+
+ After a prefix, a variable name must start with a noun or an
+adjective (such as name or long) and it should end with a noun. Some
+kind of abbreviation is permitted, as long as it wouldn't make code
+less readable (e.g. i18n).
+
+ If a variable is global in the scope of a single file (i.e. it is
+declared with static), its name may not start with any prefix. It must
+start with a noun or an adjective.
+
+ If a variable is local, you may choose any shorter name, as long as
+it wouldn't make code less readable (e.g. i).
+
+
+File: grub-dev.info, Node: Types, Next: Macros, Prev: Variables, Up: Coding style
+
+2.4 Types
+=========
+
+The name of a type must be prefixed with grub_ and must consist of only
+small letters. If the type belongs to a specific function module, the
+name must also be prefixed with the module name. For example, if a type
+is for OS loaders, its name is prefixed with grub_loader_. If a type is
+for Multiboot but not for all OS loaders, its name is prefixed with
+grub_loader_linux_.
+
+ The name must be suffixed with _t, to emphasize the fact that it is
+a type but not a variable or a function.
+
+
+File: grub-dev.info, Node: Macros, Next: Comments, Prev: Types, Up: Coding style
+
+2.5 Macros
+==========
+
+If a macro is global, its name must be prefixed with GRUB_ and must
+consist of only large letters. Other rules are the same as functions or
+variables, depending on whether a macro is used like a function or a
+variable.
+
+
+File: grub-dev.info, Node: Comments, Next: Multi-Line Comments, Prev: Macros, Up: Coding style
+
+2.6 Comments
+============
+
+All comments shall be C-style comments, of the form `/* ... */'.
+
+ Comments shall be placed only on a line by themselves. They shall
+not be placed together with code, variable declarations, or other
+non-comment entities. A comment should be placed immediately preceding
+the entity it describes.
+
+ Acceptable:
+ /* The page # that is the front buffer. */
+ int displayed_page;
+ /* The page # that is the back buffer. */
+ int render_page;
+
+ Unacceptable:
+ int displayed_page; /* The page # that is the front buffer. */
+ int render_page; /* The page # that is the back buffer. */
+
+
+File: grub-dev.info, Node: Multi-Line Comments, Prev: Comments, Up: Coding style
+
+2.7 Multi-Line Comments
+=======================
+
+Comments spanning multiple lines shall be formatted with all lines
+after the first aligned with the first line.
+
+ Asterisk characters should not be repeated a the start of each
+subsequent line.
+
+ Acceptable:
+ /* This is a comment
+ which spans multiple lines.
+ It is long. */
+
+ Unacceptable:
+ /*
+ * This is a comment
+ * which spans multiple lines.
+ * It is long. */
+
+ The opening `/*' and closing `*/' should be placed together on a
+line with text.
+
+
+File: grub-dev.info, Node: Finding your way around, Next: Coding style, Prev: Getting the source code, Up: Top
+
+3 Finding your way around
+*************************
+
+Here is a brief map of the GRUB code base.
+
+ GRUB uses Autoconf and Automake, with most of the Automake input
+generated by AutoGen. The top-level build rules are in `configure.ac',
+`grub-core/Makefile.core.def', and `Makefile.util.def'. Each block in
+a `*.def' file represents a build target, and specifies the source
+files used to build it on various platforms. The `*.def' files are
+processed into AutoGen input by `gentpl.py' (which you only need to
+look at if you are extending the build system). If you are adding a new
+module which follows an existing pattern, such as a new command or a new
+filesystem implementation, it is usually easiest to grep
+`grub-core/Makefile.core.def' and `Makefile.util.def' for an existing
+example of that pattern to find out where it should be added.
+
+ In general, code that may be run at boot time is in a subdirectory of
+`grub-core', while code that is only run from within a full operating
+system is in a subdirectory of the top level.
+
+ Low-level boot code, such as the MBR implementation on PC BIOS
+systems, is in the `grub-core/boot/' directory.
+
+ The GRUB kernel is in `grub-core/kern/'. This contains core
+facilities such as the device, disk, and file frameworks, environment
+variable handling, list processing, and so on. The kernel should
+contain enough to get up to a rescue prompt. Header files for kernel
+facilities, among others, are in `include/'.
+
+ Terminal implementations are in `grub-core/term/'.
+
+ Disk access code is spread across `grub-core/disk/' (for accessing
+the disk devices themselves), `grub-core/partmap/' (for interpreting
+partition table data), and `grub-core/fs/' (for accessing filesystems).
+Note that, with the odd specialised exception, GRUB only contains code
+to _read_ from filesystems and tries to avoid containing any code to
+_write_ to filesystems; this lets us confidently assure users that GRUB
+cannot be responsible for filesystem corruption.
+
+ PCI and USB bus handling is in `grub-core/bus/'.
+
+ Video handling code is in `grub-core/video/'. The graphical menu
+system uses this heavily, but is in a separate directory,
+`grub-core/gfxmenu/'.
+
+ Most commands are implemented by files in `grub-core/commands/', with
+the following exceptions:
+
+ * A few core commands live in `grub-core/kern/corecmd.c'.
+
+ * Commands related to normal mode live under `grub-core/normal/'.
+
+ * Commands that load and boot kernels live under `grub-core/loader/'.
+
+ * The `loopback' command is really a disk device, and so lives in
+ `grub-core/disk/loopback.c'.
+
+ * The `gettext' command lives under `grub-core/gettext/'.
+
+ * The `loadfont' and `lsfonts' commands live under `grub-core/font/'.
+
+ * The `serial', `terminfo', and `background_image' commands live
+ under `grub-core/term/'.
+
+ * The `efiemu_*' commands live under `grub-core/efiemu/'.
+
+ There are a few other special-purpose exceptions; grep for them if
+they matter to you.
+
+ Utility programs meant to be run from a full operating system are in
+`util/'.
+
+
+File: grub-dev.info, Node: Contributing Changes, Next: Error Handling, Prev: Coding style, Up: Top
+
+4 Contributing changes
+**********************
+
+Contributing changes to GRUB 2 is welcomed activity. However we have a
+bit of control what kind of changes will be accepted to GRUB 2.
+Therefore it is important to discuss your changes on grub-devel mailing
+list (see MailingLists). On this page there are some basic details on
+the development process and activities.
+
+ First of all you should come up with the idea yourself what you want
+to contribute. If you do not have that beforehand you are advised to
+study this manual and try GRUB 2 out to see what you think is missing
+from there.
+
+ Here are additional pointers:
+ * `https://savannah.gnu.org/task/?group=grub GRUB's Task Tracker'
+
+ * `https://savannah.gnu.org/bugs/?group=grub GRUB's Bug Tracker'
+
+ If you intended to make changes to GRUB Legacy (<=0.97) those are
+not accepted anymore.
+
+* Menu:
+
+* Getting started::
+* Typical Developer Experience::
+* When you are approved for write access to project's files::
+
+
+File: grub-dev.info, Node: Getting started, Next: Typical Developer Experience, Up: Contributing Changes
+
+4.1 Getting started
+===================
+
+ * Always use latest GRUB 2 source code. So get that first.
+
+ For developers it is recommended always to use the newest
+ development version of GRUB 2. If development takes a long period
+ of time, please remember to keep in sync with newest developments
+ regularly so it is much easier to integrate your change in the
+ future. GRUB 2 is being developed in a Bazaar (bzr) repository.
+
+ Please check Savannah's GRUB project page for details how to get
+ newest bzr: GRUB 2 bzr Repository
+ (http://savannah.gnu.org/bzr/?group=grub)
+
+ * Compile it and try it out.
+
+ It is always good idea to first see that things work somehow and
+ after that to start to implement new features or develop fixes to
+ bugs.
+
+ * Study the code.
+
+ There are sometimes odd ways to do things in GRUB 2 code base.
+ This is mainly related to limited environment where GRUB 2 is
+ being executed. You usually do not need to understand it all so
+ it is better to only try to look at places that relates to your
+ work. Please do not hesitate to ask for help if there is something
+ that you do not understand.
+
+ * Develop a new feature.
+
+ Now that you know what to do and how it should work in GRUB 2 code
+ base, please be free to develop it. If you have not so far
+ announced your idea on grub-devel mailing list, please do it now.
+ This is to make sure you are not wasting your time working on the
+ solution that will not be integrated to GRUB 2 code base.
+
+ You might want to study our coding style before starting
+ development so you do not need to change much of the code when
+ your patch is being reviewed. (see *note Coding style::)
+
+ For every accepted patch there has to exist a ChangeLog entry. Our
+ ChangeLog consist of changes within source code and are not
+ describing about what the change logically does. Please see
+ examples from previous entries.
+
+ Also remember that GRUB 2 is licensed under GPLv3 license and that
+ usually means that you are not allowed to copy pieces of code from
+ other projects. Even if the source project's license would be
+ compatible with GPLv3, please discuss it beforehand on grub-devel
+ mailing list.
+
+ * Test your change.
+
+ Test that your change works properly. Try it out a couple of
+ times, preferably on different systems, and try to find problems
+ with it.
+
+ * Publish your change.
+
+ When you are happy with your change, first make sure it is
+ compilable with latest development version of GRUB 2. After that
+ please send a patch to grub-devel for review. Please describe in
+ your email why you made the change, what it changes and so on.
+ Please be prepared to receive even discouraging comments about
+ your patch. There is usually at least something that needs to be
+ improved in every patch.
+
+ Please use unified diff to make your patch (good match of
+ arguments for diff is `-pruN').
+
+ * Respond to received feedback.
+
+ If you are asked to modify your patch, please do that and resubmit
+ it for review. If your change is large you are required to submit
+ a copyright agreement to FSF. Please keep in mind that if you are
+ asked to submit for copyright agreement, process can take some
+ time and is mandatory in order to get your changes integrated.
+
+ If you are not on grub-devel to respond to questions, most likely
+ your patch will not be accepted. Also if problems arise from your
+ changes later on, it would be preferable that you also fix the
+ problem. So stay around for a while.
+
+ * Your patch is accepted.
+
+ Good job! Your patch will now be integrated into GRUB 2 mainline,
+ and if it didn't break anything it will be publicly available in
+ the next release.
+
+ Now you are welcome to do further improvements :)
+
+
+File: grub-dev.info, Node: Typical Developer Experience, Next: When you are approved for write access to project's files, Prev: Getting started, Up: Contributing Changes
+
+4.2 Typical Developer Experience
+================================
+
+The typical experience for a developer in this project is the following:
+
+ 1. You find yourself wanting to do something (e.g. fixing a bug).
+
+ 2. You show some result in the mailing list or the IRC.
+
+ 3. You are getting to be known to other developers.
+
+ 4. You accumulate significant amount of contribution, so copyright
+ assignment is processed.
+
+ 5. You are free to check in your changes on your own, legally
+ speaking.
+
+ At this point, it is rather annoying that you ought to ask somebody
+else every change to be checked in. For efficiency, it is far better,
+if you can commit it yourself. Therefore, our policy is to give you the
+write permission to our official repository, once you have shown your
+skill and will, and the FSF clerks have dealt with your copyright
+assignment.
+
+
+File: grub-dev.info, Node: When you are approved for write access to project's files, Prev: Typical Developer Experience, Up: Contributing Changes
+
+4.3 When you are approved for write access to project's files
+=============================================================
+
+As you might know, GRUB is hosted on
+`https://savannah.gnu.org/projects/grub Savannah', thus the membership
+is managed by Savannah. This means that, if you want to be a member of
+this project:
+
+ 1. You need to create your own account on Savannah.
+
+ 2. You can submit "Request for Inclusion" from "My Groups" on
+ Savannah.
+
+ Then, one of the admins can approve your request, and you will be a
+member. If you don't want to use the Savannah interface to submit a
+request, you can simply notify the admins by email or something else,
+alternatively. But you still need to create an account beforehand.
+
+ NOTE: we sometimes receive a "Request for Inclusion" from an unknown
+person. In this case, the request would be just discarded, since it is
+too dangerous to allow a stranger to be a member, which automatically
+gives him a commit right to the repository, both for a legal reason and
+for a technical reason.
+
+ If your intention is to just get started, please do not submit a
+inclusion request. Instead, please subscribe to the mailing list, and
+communicate first (e.g. sending a patch, asking a question, commenting
+on another message...).
+
+
+File: grub-dev.info, Node: Error Handling, Next: CIA, Prev: Contributing Changes, Up: Top
+
+5 Error Handling
+****************
+
+Error handling in GRUB 2 is based on exception handling model. As C
+language doesn't directly support exceptions, exception handling
+behavior is emulated in software.
+
+ When exception is raised, function must return to calling function.
+If calling function does not provide handling of the exception it must
+return back to its calling function and so on, until exception is
+handled. If exception is not handled before prompt is displayed, error
+message will be shown to user.
+
+ Exception information is stored on `grub_errno' global variable. If
+`grub_errno' variable contains value `GRUB_ERR_NONE', there is no active
+exception and application can continue normal processing. When
+`grub_errno' has other value, it is required that application code
+either handles this error or returns instantly to caller. If function
+is with return type `grub_err_t' is about to return `GRUB_ERR_NONE', it
+should not set `grub_errno' to that value. Only set `grub_errno' in
+cases where there is error situation.
+
+ Simple exception forwarder.
+ grub_err_t
+ forwarding_example (void)
+ {
+ /* Call function that might cause exception. */
+ foobar ();
+
+ /* No special exception handler, just forward possible exceptions. */
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ return grub_errno;
+ }
+
+ /* All is OK, do more processing. */
+
+ /* Return OK signal, to caller. */
+ return GRUB_ERR_NONE;
+ }
+
+ Error reporting has two components, the actual error code (of type
+`grub_err_t') and textual message that will be displayed to user. List
+of valid error codes is listed in header file `include/grub/err.h'.
+Textual error message can contain any textual data. At time of writing,
+error message can contain up to 256 characters (including terminating
+NUL). To ease error reporting there is a helper function `grub_error'
+that allows easier formatting of error messages and should be used
+instead of writing directly to global variables.
+
+ Example of error reporting.
+ grub_err_t
+ failing_example ()
+ {
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+ "Failed to read %s, tried %d times.",
+ "test.txt",
+ 10);
+ }
+
+ If there is a special reason that error code does not need to be
+taken account, `grub_errno' can be zeroed back to `GRUB_ERR_NONE'. In
+cases like this all previous error codes should have been handled
+correctly. This makes sure that there are no unhandled exceptions.
+
+ Example of zeroing `grub_errno'.
+ grub_err_t
+ probe_example ()
+ {
+ /* Try to probe device type 1. */
+ probe_for_device ();
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ /* Device type 1 was found on system. */
+ register_device ();
+ return GRUB_ERR_NONE;
+ }
+ /* Zero out error code. */
+ grub_errno = GRUB_ERR_NONE;
+
+ /* No device type 1 found, try to probe device type 2. */
+ probe_for_device2 ();
+ if (grub_errno == GRUB_ERR_NONE)
+ {
+ /* Device type 2 was found on system. */
+ register_device2 ();
+ return GRUB_ERR_NONE;
+ }
+ /* Zero out error code. */
+ grub_errno = GRUB_ERR_NONE;
+
+ /* Return custom error message. */
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No device type 1 or 2 found.");
+ }
+
+ Some times there is a need to continue processing even if there is a
+error state in application. In situations like this, there is a needed
+to save old error state and then call other functions that might fail.
+To aid in this, there is a error stack implemented. Error state can be
+pushed to error stack by calling function `grub_error_push ()'. When
+processing has been completed, `grub_error_pop ()' can be used to pop
+error state from stack. Error stack contains predefined amount of error
+stack items. Error stack is protected for overflow and marks these
+situations so overflow error does not get unseen. If there is no space
+available to store error message, it is simply discarded and overflow
+will be marked as happened. When overflow happens, it most likely will
+corrupt error stack consistency as for pushed error there is no matching
+pop, but overflow message will be shown to inform user about the
+situation. Overflow message will be shown at time when prompt is about
+to be drawn.
+
+ Example usage of error stack.
+ /* Save possible old error message. */
+ grub_error_push ();
+
+ /* Do your stuff here. */
+ call_possibly_failing_function ();
+
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ /* Inform rest of the code that there is error (grub_errno
+ is set). There is no pop here as we want both error states
+ to be displayed. */
+ return;
+ }
+
+ /* Restore old error state by popping previous item from stack. */
+ grub_error_pop ();
+
+
+File: grub-dev.info, Node: CIA, Next: BIOS port memory map, Prev: Error Handling, Up: Top
+
+6 CIA
+*****
+
+If you have commit access, please setup CIA in your Bazaar config so
+those in IRC receive notification of your commits.
+
+ In `~/.bazaar/bazaar.conf', add "cia_send_revno = true".
+Optionally, you can also add "cia_user = myusername" if you'd like CIA
+service to use a specific account (for statistical purpose).
+
+ In the `.bzr/branch/branch.conf' of your checkout branch, "set
+nickname = /path_to_this_branch" and "cia_project = GNU GRUB".
+
+ Additionally, please set cia_send_revno in the [DEFAULT] section of
+your `~/.bazaar/bazaar.conf'. E.g.:
+
+ [DEFAULT]
+ cia_send_revno = true
+
+ Remember to install cia-clients (Debian/Ubuntu package) to be able
+to use CIA.
+
+ Keep in mind Bazaar sends notifications for all commits to branches
+that have this setting, regardless of whether they're bound branches
+(checkouts) or not. So if you make local commits in a non-bound branch
+and it bothers you that others can read them, do not use this setting.
+
+
+File: grub-dev.info, Node: BIOS port memory map, Next: Video Subsystem, Prev: CIA, Up: Top
+
+7 BIOS port memory map
+**********************
+
+Start End Usage
+--------------------------------------------------------------------
+0 0x1000 - 1 BIOS and real mode interrupts
+0x07BE 0x07FF Partition table passed to another
+ boot loader
+? 0x2000 - 1 Real mode stack
+0x7C00 0x7D00 - 1 Boot sector
+0x8000 ? GRUB kernel
+0x68000 0x78000 - 1 Disk buffer
+? 0x80000 - 1 Protected mode stack
+0x80000 ? Heap
+? 0xA0000 - 1 Extended BIOS Data Area
+0xA0000 0xC0000 - 1 Video RAM
+0xC0000 0x100000 - 1 BIOS
+0x100000 ? Heap and module code
+
+
+File: grub-dev.info, Node: Video Subsystem, Next: PFF2 Font File Format, Prev: BIOS port memory map, Up: Top
+
+8 Video Subsystem
+*****************
+
+This document contains specification for Video Subsystem for GRUB2.
+Currently only the usage interface is described in this document.
+Internal structure of how video drivers are registering and how video
+driver manager works are not included here.
+
+* Menu:
+
+* Video API::
+* Bitmap API::
+* Example usage of Video API::
+
+
+File: grub-dev.info, Node: Video API, Next: Bitmap API, Up: Video Subsystem
+
+8.1 Video API
+=============
+
+8.1.1 grub_video_setup
+----------------------
+
+ * Prototype:
+ grub_err_t
+ grub_video_setup (unsigned int width, unsigned int height, unsigned int mode_type);
+
+ * Description:
+
+ Driver will use information provided to it to select best possible
+ video mode and switch to it. Supported values for `mode_type' are
+ `GRUB_VIDEO_MODE_TYPE_INDEX_COLOR' for index color modes,
+ `GRUB_VIDEO_MODE_TYPE_RGB' for direct RGB color modes and
+ `GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED' for double buffering. When
+ requesting RGB mode, highest bits per pixel mode will be selected.
+ When requesting Index color mode, mode with highest number of
+ colors will be selected. If all parameters are specified as zero,
+ video adapter will try to figure out best possible mode and
+ initialize it, platform specific differences are allowed here. If
+ there is no mode matching request, error X will be returned. If
+ there are no problems, function returns `GRUB_ERR_NONE'.
+
+ This function also performs following task upon succesful mode
+ switch. Active rendering target is changed to screen and viewport
+ is maximized to allow whole screen to be used when performing
+ graphics operations. In RGB modes, emulated palette gets 16
+ entries containing default values for VGA palette, other colors
+ are defined as black. When switching to Indexed Color mode, driver
+ may set default VGA palette to screen if the video card allows the
+ operation.
+
+
+8.1.2 grub_video_restore
+------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_restore (void);
+
+ * Description:
+
+ Video subsystem will deinitialize activated video driver to
+ restore old state of video device. This can be used to switch back
+ to text mode.
+
+8.1.3 grub_video_get_info
+-------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_get_info (struct grub_video_mode_info *mode_info);
+
+ struct grub_video_mode_info
+ {
+ /* Width of the screen. */
+ unsigned int width;
+ /* Height of the screen. */
+ unsigned int height;
+ /* Mode type bitmask. Contains information like is it Index color or
+ RGB mode. */
+ unsigned int mode_type;
+ /* Bits per pixel. */
+ unsigned int bpp;
+ /* Bytes per pixel. */
+ unsigned int bytes_per_pixel;
+ /* Pitch of one scanline. How many bytes there are for scanline. */
+ unsigned int pitch;
+ /* In index color mode, number of colors. In RGB mode this is 256. */
+ unsigned int number_of_colors;
+ /* Optimization hint how binary data is coded. */
+ enum grub_video_blit_format blit_format;
+ /* How many bits are reserved for red color. */
+ unsigned int red_mask_size;
+ /* What is location of red color bits. In Index Color mode, this is 0. */
+ unsigned int red_field_pos;
+ /* How many bits are reserved for green color. */
+ unsigned int green_mask_size;
+ /* What is location of green color bits. In Index Color mode, this is 0. */
+ unsigned int green_field_pos;
+ /* How many bits are reserved for blue color. */
+ unsigned int blue_mask_size;
+ /* What is location of blue color bits. In Index Color mode, this is 0. */
+ unsigned int blue_field_pos;
+ /* How many bits are reserved in color. */
+ unsigned int reserved_mask_size;
+ /* What is location of reserved color bits. In Index Color mode,
+ this is 0. */
+ unsigned int reserved_field_pos;
+ };
+
+ * Description:
+
+ Software developer can use this function to query properties of
+ active rendering taget. Information provided here can be used by
+ other parts of GRUB, like image loaders to convert loaded images
+ to correct screen format to allow more optimized blitters to be
+ used. If there there is no configured video driver with active
+ screen, error `GRUB_ERR_BAD_DEVICE' is returned, otherwise
+ `mode_info' is filled with valid information and `GRUB_ERR_NONE'
+ is returned.
+
+8.1.4 grub_video_get_blit_format
+--------------------------------
+
+ * Prototype:
+
+ enum grub_video_blit_format
+ grub_video_get_blit_format (struct grub_video_mode_info *mode_info);
+
+ enum grub_video_blit_format
+ {
+ /* Follow exactly field & mask information. */
+ GRUB_VIDEO_BLIT_FORMAT_RGBA,
+ /* Make optimization assumption. */
+ GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8,
+ /* Follow exactly field & mask information. */
+ GRUB_VIDEO_BLIT_FORMAT_RGB,
+ /* Make optimization assumption. */
+ GRUB_VIDEO_BLIT_FORMAT_R8G8B8,
+ /* When needed, decode color or just use value as is. */
+ GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR
+ };
+
+ * Description:
+
+ Used to query how data could be optimized to suit specified video
+ mode. Returns exact video format type, or a generic one if there
+ is no definition for the type. For generic formats, use
+ `grub_video_get_info' to query video color coding settings.
+
+8.1.5 grub_video_set_palette
+----------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data);
+
+ struct grub_video_palette_data
+ {
+ grub_uint8_t r; /* Red color value (0-255). */
+ grub_uint8_t g; /* Green color value (0-255). */
+ grub_uint8_t b; /* Blue color value (0-255). */
+ grub_uint8_t a; /* Reserved bits value (0-255). */
+ };
+
+ * Description:
+
+ Used to setup indexed color palettes. If mode is RGB mode, colors
+ will be set to emulated palette data. In Indexed Color modes,
+ palettes will be set to hardware. Color values will be converted
+ to suit requirements of the video mode. `start' will tell what
+ hardware color index (or emulated color index) will be set to
+ according information in first indice of `palette_data', after
+ that both hardware color index and `palette_data' index will be
+ incremented until `count' number of colors have been set.
+
+8.1.6 grub_video_get_palette
+----------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_get_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data);
+
+ struct grub_video_palette_data
+ {
+ grub_uint8_t r; /* Red color value (0-255). */
+ grub_uint8_t g; /* Green color value (0-255). */
+ grub_uint8_t b; /* Blue color value (0-255). */
+ grub_uint8_t a; /* Reserved bits value (0-255). */
+ };
+
+ * Description:
+
+ Used to query indexed color palettes. If mode is RGB mode, colors
+ will be copied from emulated palette data. In Indexed Color modes,
+ palettes will be read from hardware. Color values will be
+ converted to suit structure format. `start' will tell what
+ hardware color index (or emulated color index) will be used as a
+ source for first indice of `palette_data', after that both
+ hardware color index and `palette_data' index will be incremented
+ until `count' number of colors have been read.
+
+8.1.7 grub_video_set_viewport
+-----------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_set_viewport (unsigned int x, unsigned int y, unsigned int width, unsigned int height);
+
+ * Description:
+
+ Used to specify viewport where draw commands are performed. When
+ viewport is set, all draw commands coordinates relate to those
+ specified by `x' and `y'. If draw commands try to draw over
+ viewport, they are clipped. If developer requests larger than
+ possible viewport, width and height will be clamped to fit screen.
+ If `x' and `y' are out of bounds, all functions drawing to screen
+ will not be displayed. In order to maximize viewport, use
+ `grub_video_get_info' to query actual screen dimensions and
+ provide that information to this function.
+
+8.1.8 grub_video_get_viewport
+-----------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_get_viewport (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height);
+
+ * Description:
+
+ Used to query current viewport dimensions. Software developer can
+ use this to choose best way to render contents of the viewport.
+
+8.1.9 grub_video_map_color
+--------------------------
+
+ * Prototype:
+
+ grub_video_color_t
+ grub_video_map_color (grub_uint32_t color_name);
+
+ * Description:
+
+ Map color can be used to support color themes in GRUB. There will
+ be collection of color names that can be used to query actual
+ screen mapped color data. Examples could be
+ `GRUB_COLOR_CONSOLE_BACKGROUND', `GRUB_COLOR_CONSOLE_TEXT'. The
+ actual color defines are not specified at this point.
+
+8.1.10 grub_video_map_rgb
+-------------------------
+
+ * Prototype:
+
+ grub_video_color_t
+ grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue);
+
+ * Description:
+
+ Map RGB values to compatible screen color data. Values are
+ expected to be in range 0-255 and in RGB modes they will be
+ converted to screen color data. In index color modes, index color
+ palette will be searched for specified color and then index is
+ returned.
+
+8.1.11 grub_video_map_rgba
+--------------------------
+
+ * Prototype:
+
+ grub_video_color_t
+ grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue, grub_uint8_t alpha);
+
+ * Description:
+
+ Map RGBA values to compatible screen color data. Values are
+ expected to be in range 0-255. In RGBA modes they will be
+ converted to screen color data. In index color modes, index color
+ palette will be searched for best matching color and its index is
+ returned.
+
+8.1.12 grub_video_unmap_color
+-----------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red, grub_uint8_t *green, grub_uint8_t *blue, grub_uint8_t *alpha);
+
+ * Description:
+
+ Unmap color value from `color' to color channels in `red',
+ `green', `blue' and `alpha'. Values will be in range 0-255. Active
+ rendering target will be used for color domain. In case alpha
+ information is not available in rendering target, it is assumed to
+ be opaque (having value 255).
+
+8.1.13 grub_video_fill_rect
+---------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_fill_rect (grub_video_color_t color, int x, int y, unsigned int width, unsigned int height);
+
+ * Description:
+
+ Fill specified area limited by given coordinates within specified
+ viewport. Negative coordinates are accepted in order to allow easy
+ moving of rectangle within viewport. If coordinates are negative,
+ area of the rectangle will be shrinken to follow size limits of
+ the viewport.
+
+ Software developer should use either `grub_video_map_color',
+ `grub_video_map_rgb' or `grub_video_map_rgba' to map requested
+ color to `color' parameter.
+
+8.1.14 grub_video_blit_glyph
+----------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_blit_glyph (struct grub_font_glyph *glyph, grub_video_color_t color, int x, int y);
+
+ struct grub_font_glyph {
+ /* TBD. */
+ };
+
+ * Description:
+
+ Used to blit glyph to viewport in specified coodinates. If glyph
+ is at edge of viewport, pixels outside of viewport will be clipped
+ out. Software developer should use either `grub_video_map_rgb' or
+ `grub_video_map_rgba' to map requested color to `color' parameter.
+
+8.1.15 grub_video_blit_bitmap
+-----------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, unsigned int width, unsigned int height);
+
+ struct grub_video_bitmap
+ {
+ /* TBD. */
+ };
+
+ enum grub_video_blit_operators
+ {
+ GRUB_VIDEO_BLIT_REPLACE,
+ GRUB_VIDEO_BLIT_BLEND
+ };
+
+ * Description:
+
+ Used to blit bitmap to viewport in specified coordinates. If part
+ of bitmap is outside of viewport region, it will be clipped out.
+ Offsets affect bitmap position where data will be copied from.
+ Negative values for both viewport coordinates and bitmap offset
+ coordinates are allowed. If data is looked out of bounds of
+ bitmap, color value will be assumed to be transparent. If viewport
+ coordinates are negative, area of the blitted rectangle will be
+ shrinken to follow size limits of the viewport and bitmap.
+ Blitting operator `oper' specifies should source pixel replace
+ data in screen or blend with pixel alpha value.
+
+ Software developer should use `grub_video_bitmap_create' or
+ `grub_video_bitmap_load' to create or load bitmap data.
+
+8.1.16 grub_video_blit_render_target
+------------------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_blit_render_target (struct grub_video_render_target *source, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, unsigned int width, unsigned int height);
+
+ struct grub_video_render_target {
+ /* This is private data for video driver. Should not be accessed from elsewhere directly. */
+ };
+
+ enum grub_video_blit_operators
+ {
+ GRUB_VIDEO_BLIT_REPLACE,
+ GRUB_VIDEO_BLIT_BLEND
+ };
+
+ * Description:
+
+ Used to blit source render target to viewport in specified
+ coordinates. If part of source render target is outside of
+ viewport region, it will be clipped out. If blitting operator is
+ specified and source contains alpha values, resulting pixel color
+ components will be calculated using formula ((src_color *
+ src_alpha) + (dst_color * (255 - src_alpha)) / 255, if target
+ buffer has alpha, it will be set to src_alpha. Offsets affect
+ render target position where data will be copied from. If data is
+ looked out of bounds of render target, color value will be assumed
+ to be transparent. Blitting operator `oper' specifies should
+ source pixel replace data in screen or blend with pixel alpha
+ value.
+
+8.1.17 grub_video_scroll
+------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_scroll (grub_video_color_t color, int dx, int dy);
+
+ * Description:
+
+ Used to scroll viewport to specified direction. New areas are
+ filled with specified color. This function is used when screen is
+ scroller up in video terminal.
+
+8.1.18 grub_video_swap_buffers
+------------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_swap_buffers (void);
+
+ * Description:
+
+ If double buffering is enabled, this swaps frontbuffer and
+ backbuffer, in order to show values drawn to back buffer. Video
+ driver is free to choose how this operation is techincally done.
+
+8.1.19 grub_video_create_render_target
+--------------------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_create_render_target (struct grub_video_render_target **result, unsigned int width, unsigned int height, unsigned int mode_type);
+
+ struct grub_video_render_target {
+ /* This is private data for video driver. Should not be accessed from elsewhere directly. */
+ };
+
+ * Description:
+
+ Driver will use information provided to it to create best fitting
+ render target. `mode_type' will be used to guide on selecting what
+ features are wanted for render target. Supported values for
+ `mode_type' are `GRUB_VIDEO_MODE_TYPE_INDEX_COLOR' for index color
+ modes, `GRUB_VIDEO_MODE_TYPE_RGB' for direct RGB color modes and
+ `GRUB_VIDEO_MODE_TYPE_ALPHA' for alpha component.
+
+8.1.20 grub_video_delete_render_target
+--------------------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_delete_render_target (struct grub_video_render_target *target);
+
+ * Description:
+
+ Used to delete previously created render target. If `target'
+ contains `NULL' pointer, nothing will be done. If render target is
+ correctly destroyed, GRUB_ERR_NONE is returned.
+
+8.1.21 grub_video_set_active_render_target
+------------------------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_set_active_render_target (struct grub_video_render_target *target);
+
+ * Description:
+
+ Sets active render target. If this comand is successful all
+ drawing commands will be done to specified `target'. There is also
+ special values for target, `GRUB_VIDEO_RENDER_TARGET_DISPLAY' used
+ to reference screen's front buffer,
+ `GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER' used to reference screen's
+ front buffer (alias for `GRUB_VIDEO_RENDER_TARGET_DISPLAY') and
+ `GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER' used to reference back
+ buffer (if double buffering is enabled). If render target is
+ correclty switched GRUB_ERR_NONE is returned. In no any event
+ shall there be non drawable active render target.
+
+
+8.1.22 grub_video_get_active_render_target
+------------------------------------------
+
+ * Prototype:
+
+ grub_err_t
+ grub_video_get_active_render_target (struct grub_video_render_target **target);
+
+ * Description:
+
+ Returns currently active render target. It returns value in
+ `target' that can be subsequently issued back to
+ `grub_video_set_active_render_target'.
+
+
+File: grub-dev.info, Node: Example usage of Video API, Prev: Bitmap API, Up: Video Subsystem
+
+8.2 Example usage of Video API
+==============================
+
+8.2.1 Example of screen setup
+-----------------------------
+
+ grub_err_t rc;
+ /* Try to initialize video mode 1024 x 768 with direct RGB. */
+ rc = grub_video_setup (1024, 768, GRUB_VIDEO_MODE_TYPE_RGB);
+ if (rc != GRUB_ERR_NONE)
+ {
+ /* Fall back to standard VGA Index Color mode. */
+ rc = grub_video_setup (640, 480, GRUB_VIDEO_MODE_TYPE_INDEX);
+ if (rc != GRUB_ERR_NONE)
+ {
+ /* Handle error. */
+ }
+ }
+
+8.2.2 Example of setting up console viewport
+--------------------------------------------
+
+ grub_uint32_t x, y, width, height;
+ grub_video_color_t color;
+ struct grub_font_glyph glyph;
+ grub_err_t rc;
+ /* Query existing viewport. */
+ grub_video_get_viewport (&x, &y, &width, &height);
+ /* Fill background. */
+ color = grub_video_map_color (GRUB_COLOR_BACKGROUND);
+ grub_video_fill_rect (color, 0, 0, width, height);
+ /* Setup console viewport. */
+ grub_video_set_viewport (x + 10, y + 10, width - 20, height - 20);
+ grub_video_get_viewport (&x, &y, &width, &height);
+ color = grub_video_map_color (GRUB_COLOR_CONSOLE_BACKGROUND);
+ grub_video_fill_rect (color, 0, 0, width, height);
+ /* Draw text to viewport. */
+ color = grub_video_map_color (GRUB_COLOR_CONSOLE_TEXT);
+ grub_font_get_glyph ('X', &glyph);
+ grub_video_blit_glyph (&glyph, color, 0, 0);
+
+
+File: grub-dev.info, Node: Bitmap API, Next: Example usage of Video API, Prev: Video API, Up: Video Subsystem
+
+8.3 Bitmap API
+==============
+
+8.3.1 grub_video_bitmap_create
+------------------------------
+
+ * Prototype:
+ grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap, unsigned int width, unsigned int height, enum grub_video_blit_format blit_format)
+
+ * Description:
+
+ Creates a new bitmap with given dimensions and blitting format.
+ Allocated bitmap data can then be modified freely and finally
+ blitted with `grub_video_blit_bitmap' to rendering target.
+
+8.3.2 grub_video_bitmap_destroy
+-------------------------------
+
+ * Prototype:
+ grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap);
+
+ * Description:
+
+ When bitmap is no longer needed, it can be freed from memory using
+ this command. `bitmap' is previously allocated bitmap with
+ `grub_video_bitmap_create' or loaded with `grub_video_bitmap_load'.
+
+8.3.3 grub_video_bitmap_load
+----------------------------
+
+ * Prototype:
+ grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap, const char *filename);
+
+ * Description:
+
+ Tries to load given bitmap (`filename') using registered bitmap
+ loaders. In case bitmap format is not recognized or supported
+ error `GRUB_ERR_BAD_FILE_TYPE' is returned.
+
+8.3.4 grub_video_bitmap_get_width
+---------------------------------
+
+ * Prototype:
+ unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap);
+
+ * Description:
+
+ Returns bitmap width.
+
+8.3.5 grub_video_bitmap_get_height
+----------------------------------
+
+ * Prototype:
+ unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap);
+
+ * Description:
+
+ Return bitmap height.
+
+8.3.6 grub_video_bitmap_get_mode_info
+-------------------------------------
+
+ * Prototype:
+ void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, struct grub_video_mode_info *mode_info);
+
+ * Description:
+
+ Returns bitmap format details in form of `grub_video_mode_info'.
+
+8.3.7 grub_video_bitmap_get_data
+--------------------------------
+
+ * Prototype:
+ void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap);
+
+ * Description:
+
+ Return pointer to bitmap data. Contents of the pointed data can be
+ freely modified. There is no extra protection against going off
+ the bounds so you have to be carefull how to access the data.
+
+
+File: grub-dev.info, Node: PFF2 Font File Format, Next: Graphical Menu Software Design, Prev: Video Subsystem, Up: Top
+
+9 PFF2 Font File Format
+***********************
+
+* Menu:
+
+* Introduction::
+* File Structure::
+* Font Metrics::
+
+
+File: grub-dev.info, Node: Introduction, Next: File Structure, Up: PFF2 Font File Format
+
+9.1 Introduction
+================
+
+The goal of this format is to provide a bitmap font format that is
+simple to use, compact, and cleanly supports Unicode.
+
+9.1.1 Goals of the GRUB Font Format
+-----------------------------------
+
+ * Simple to read and use. Since GRUB will only be reading the font
+ files, we are more concerned with making the code to read the font
+ simple than we are with writing the font.
+
+ * Compact storage. The fonts will generally be stored in a small
+ boot partition where GRUB is located, and this may be on a
+ removable storage device such as a CD or USB flash drive where
+ space is more limited than it is on most hard drives.
+
+ * Unicode. GRUB should not have to deal with multiple character
+ encodings. The font should always use Unicode character codes for
+ simple internationalization.
+
+9.1.2 Why Another Font Format?
+------------------------------
+
+There are many existing bitmap font formats that GRUB could use.
+However, there are aspects of these formats that may make them less
+than suitable for use in GRUB at this time:
+
+`BDF'
+ Inefficient storage; uses ASCII to describe properties and
+ hexadecimal numbers in ASCII for the bitmap rows.
+
+`PCF'
+ Many format variations such as byte order and bitmap padding (rows
+ padded to byte, word, etc.) would result in more complex code to
+ handle the font format.
+
+
+File: grub-dev.info, Node: File Structure, Next: Font Metrics, Prev: Introduction, Up: PFF2 Font File Format
+
+9.2 File Structure
+==================
+
+A file *section* consists of a 4-byte name, a 32-bit big-endian length
+(not including the name or length), and then LENGTH more
+section-type-specific bytes.
+
+ The standard file extension for PFF2 font files is `.pf2'.
+
+9.2.1 Section Types
+-------------------
+
+`FILE'
+ *File type ID* (ASCII string). This must be the first section in
+ the file. It has length 4 and the contents are the four bytes of
+ the ASCII string `PFF2'.
+
+`NAME'
+ *Font name* (ASCII string). This is the full font name including
+ family, weight, style, and point size. For instance, "Helvetica
+ Bold Italic 14".
+
+`FAMI'
+ *Font family name* (ASCII string). For instance, "Helvetica".
+ This should be included so that intelligent font substitution can
+ take place.
+
+`WEIG'
+ *Font weight* (ASCII string). Valid values are `bold' and
+ `normal'. This should be included so that intelligent font
+ substitution can take place.
+
+`SLAN'
+ *Font slant* (ASCII string). Valid values are `italic' and
+ `normal'. This should be included so that intelligent font
+ substitution can take place.
+
+`PTSZ'
+ *Font point size* (uint16be).
+
+`MAXW'
+ *Maximum character width in pixels* (uint16be).
+
+`MAXH'
+ *Maximum character height in pixels* (uint16be).
+
+`ASCE'
+ *Ascent in pixels* (uint16be). *Note Font Metrics::, for details.
+
+`DESC'
+ *Descent in pixels* (uint16be). *Note Font Metrics::, for details.
+
+`CHIX'
+ *Character index.* The character index begins with a 32-bit
+ big-endian unsigned integer indicating the total size of the
+ section, not including this size value. For each character, there
+ is an instance of the following entry structure:
+
+ * *Unicode code point.* (32-bit big-endian integer.)
+
+ * *Storage flags.* (byte.)
+
+ * Bits 2..0:
+
+ If equal to 000 binary, then the character data is stored
+ uncompressed beginning at the offset indicated by the
+ character's *offset* value.
+
+ If equal to 001 binary, then the character data is
+ stored within a compressed character definition block
+ that begins at the offset within the file indicated by
+ the character's *offset* value.
+
+ * *Offset.* (32-bit big-endian integer.)
+
+ A marker that indicates the remainder of the file is data
+ accessed via the character index (CHIX) section. When
+ reading this font file, the rest of the file can be ignored
+ when scanning the sections. The length should be set to -1
+ (0xFFFFFFFF).
+
+ Supported data structures:
+
+ Character definition Each character definition consists of:
+
+ * *Width.* Width of the bitmap in pixels. The bitmap's
+ extents represent the glyph's bounding box. `uint16be'.
+
+ * *Height.* Height of the bitmap in pixels. The bitmap's
+ extents represent the glyph's bounding box. `uint16be'.
+
+ * *X offset.* The number of pixels to shift the bitmap by
+ horizontally before drawing the character. `int16be'.
+
+ * *Y offset.* The number of pixels to shift the bitmap by
+ vertically before drawing the character. `int16be'.
+
+ * *Device width.* The number of pixels to advance
+ horizontally from this character's origin to the origin
+ of the next character. `int16be'.
+
+ * *Bitmap data.* This is encoded as a string of bits. It
+ is organized as a row-major, top-down, left-to-right
+ bitmap. The most significant bit of each byte is taken
+ to be the leftmost or uppermost bit in the byte. For
+ the sake of compact storage, rows are not padded to byte
+ boundaries (i.e., a single byte may contain bits
+ belonging to multiple rows). The last byte of the
+ bitmap *is* padded with zero bits in the bits positions
+ to the right of the last used bit if the bitmap data
+ does not fill the last byte.
+
+ The length of the *bitmap data* field is (WIDTH * HEIGHT
+ + 7) / 8 using integer arithmetic, which is equivalent
+ to ceil(WIDTH * HEIGHT / 8) using real number arithmetic.
+
+ It remains to be determined whether bitmap fonts usually
+ make all glyph bitmaps the same height, or if smaller
+ glyphs are stored with bitmaps having a lesser height.
+ In the latter case, the baseline would have to be used
+ to calculate the location the bitmap should be anchored
+ at on screen.
+
+
+
+File: grub-dev.info, Node: Font Metrics, Prev: File Structure, Up: PFF2 Font File Format
+
+9.3 Font Metrics
+================
+
+ * Ascent. The distance from the baseline to the top of most
+ characters. Note that in some cases characters may extend above
+ the ascent.
+
+ * Descent. The distance from the baseline to the bottom of most
+ characters. Note that in some cases characters may extend below
+ the descent.
+
+ * Leading. The amount of space, in pixels, to leave between the
+ descent of one line of text and the ascent of the next line. This
+ metrics is not specified in the current file format; instead, the
+ font rendering engine calculates a reasonable leading value based
+ on the other font metrics.
+
+ * Horizonal leading. The amount of space, in pixels, to leave
+ horizontally between the left and right edges of two adjacent
+ glyphs. The *device width* field determines the effective leading
+ value that is used to render the font.
+
+[Please fill this in.
+]
+
+ An illustration of how the various font metrics apply to characters.
+
+
+File: grub-dev.info, Node: Graphical Menu Software Design, Next: Copying This Manual, Prev: PFF2 Font File Format, Up: Top
+
+10 Graphical Menu Software Design
+*********************************
+
+* Menu:
+
+* Introduction_2::
+* Startup Sequence::
+* GUI Components::
+* Command Line Window::
+
+
+File: grub-dev.info, Node: Introduction_2, Next: Startup Sequence, Up: Graphical Menu Software Design
+
+10.1 Introduction
+=================
+
+The `gfxmenu' module provides a graphical menu interface for GRUB 2. It
+functions as an alternative to the menu interface provided by the
+`normal' module, which uses the grub terminal interface to display a
+menu on a character-oriented terminal.
+
+ The graphical menu uses the GRUB video API, which is currently for
+the VESA BIOS extensions (VBE) 2.0+. This is supported on the i386-pc
+platform. However, the graphical menu itself does not depend on using
+VBE, so if another GRUB video driver were implemented, the `gfxmenu'
+graphical menu would work on the new video driver as well.
+
+
+File: grub-dev.info, Node: Startup Sequence, Next: GUI Components, Prev: Introduction_2, Up: Graphical Menu Software Design
+
+10.2 Startup Sequence
+=====================
+
+ * grub_enter_normal_mode [normal/main.c]
+
+ * grub_normal_execute [normal/main.c]
+
+ * read_config_file [normal/main.c]
+
+ * (When `gfxmenu.mod' is loaded with `insmod', it will call
+ `grub_menu_viewer_register()' to register itself.)
+
+ * GRUB_MOD_INIT (gfxmenu) [gfxmenu/gfxmenu.c]
+
+ * grub_menu_viewer_register [kern/menu_viewer.c]
+
+ * grub_menu_viewer_show_menu [kern/menu_viewer.c]
+
+ * get_current_menu_viewer() [kern/menu_viewer.c]
+
+ * show_menu() [gfxmenu/gfxmenu.c]
+
+ * grub_gfxmenu_model_new [gfxmenu/model.c]
+
+ * grub_gfxmenu_view_new [gfxmenu/view.c]
+
+ * set_graphics_mode [gfxmenu/view.c]
+
+ * grub_gfxmenu_view_load_theme [gfxmenu/theme_loader.c]
+
+
+File: grub-dev.info, Node: GUI Components, Next: Command Line Window, Prev: Startup Sequence, Up: Graphical Menu Software Design
+
+10.3 GUI Components
+===================
+
+The graphical menu implements a GUI component system that supports a
+container-based layout system. Components can be added to containers,
+and containers (which are a type of component) can then be added to
+other containers, to form a tree of components. Currently, the root
+component of this tree is a `canvas' component, which allows manual
+layout of its child components.
+
+ Components (non-container):
+
+ * label
+
+ * image
+
+ * progress_bar
+
+ * circular_progress
+
+ * list (currently hard coded to be a boot menu list)
+
+ Containers:
+
+ * canvas
+
+ * hbox
+
+ * vbox
+
+ The GUI component instances are created by the theme loader in
+`gfxmenu/theme_loader.c' when a theme is loaded. Theme files specify
+statements such as `+vbox{ +label { text="Hello" } +label{ text="World"
+} }' to add components to the component tree root. By nesting the
+component creation statements in the theme file, the instantiated
+components are nested the same way.
+
+ When a component is added to a container, that new child is
+considered *owned* by the container. Great care should be taken if the
+caller retains a reference to the child component, since it will be
+destroyed if its parent container is destroyed. A better choice
+instead of storing a pointer to the child component is to use the
+component ID to find the desired component. Component IDs do not have
+to be unique (it is often useful to have multiple components with an ID
+of "__timeout__", for instance).
+
+ In order to access and use components in the component tree, there
+are two functions (defined in `gfxmenu/gui_util.c') that are
+particularly useful:
+
+ * `grub_gui_find_by_id (root, id, callback, userdata)':
+
+ This function ecursively traverses the component tree rooted at
+ ROOT, and for every component that has an ID equal to ID, calls
+ the function pointed to by CALLBACK with the matching component
+ and the void pointer USERDATA as arguments. The callback function
+ can do whatever is desired to use the component passed in.
+
+ * `grub_gui_iterate_recursively (root, callback, userdata)':
+
+ This function calls the function pointed to by CALLBACK for every
+ component that is a descendant of ROOT in the component tree.
+ When the callback function is called, the component and the void
+ pointer USERDATA as arguments. The callback function can do
+ whatever is desired to use the component passed in.
+
+
+File: grub-dev.info, Node: Command Line Window, Prev: GUI Components, Up: Graphical Menu Software Design
+
+10.4 Command Line Window
+========================
+
+The terminal window used to provide command line access within the
+graphical menu is managed by `gfxmenu/view.c'. The `gfxterm' terminal
+is used, and it has been modified to allow rendering to an offscreen
+render target to allow it to be composed into the double buffering
+system that the graphical menu view uses. This is bad for performance,
+however, so it would probably be a good idea to make it possible to
+temporarily disable double buffering as long as the terminal window is
+visible. There are still unresolved problems that occur when commands
+are executed from the terminal window that change the graphics mode.
+It's possible that making `grub_video_restore()' return to the graphics
+mode that was in use before `grub_video_setup()' was called might fix
+some of the problems.
+
+
+File: grub-dev.info, Node: Copying This Manual, Next: Index, Prev: Graphical Menu Software Design, Up: Top
+
+Appendix A Copying This Manual
+******************************
+
+* Menu:
+
+* GNU Free Documentation License:: License for copying this manual.
+
+
+File: grub-dev.info, Node: GNU Free Documentation License, Up: Copying This Manual
+
+A.1 GNU Free Documentation License
+==================================
+
+ Version 1.2, November 2002
+
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided for under this License. Any other
+ attempt to copy, modify, sublicense or distribute the Document is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses
+ terminated so long as such parties remain in full compliance.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.
+
+A.1.1 ADDENDUM: How to use this License for your documents
+----------------------------------------------------------
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+
+File: grub-dev.info, Node: Index, Prev: Copying This Manual, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* FDL, GNU Free Documentation License: GNU Free Documentation License.
+ (line 6)
+
+
+
+Tag Table:
+Node: Top718
+Node: Getting the source code1780
+Node: Coding style2660
+Node: Naming Conventions3065
+Node: Functions3348
+Node: Variables4215
+Node: Types5321
+Node: Macros5919
+Node: Comments6250
+Node: Multi-Line Comments7012
+Node: Finding your way around7643
+Node: Contributing Changes10840
+Node: Getting started11924
+Node: Typical Developer Experience15970
+Node: When you are approved for write access to project's files17013
+Node: Error Handling18443
+Node: CIA23516
+Node: BIOS port memory map24588
+Node: Video Subsystem25458
+Node: Video API25930
+Node: Example usage of Video API44184
+Node: Bitmap API45740
+Node: PFF2 Font File Format48271
+Node: Introduction48509
+Node: File Structure50006
+Node: Font Metrics54909
+Node: Graphical Menu Software Design56011
+Node: Introduction_256303
+Node: Startup Sequence57037
+Node: GUI Components57900
+Node: Command Line Window60505
+Node: Copying This Manual61457
+Node: GNU Free Documentation License61713
+Node: Index84125
+
+End Tag Table
diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
new file mode 100644
index 0000000..93d2bdb
--- /dev/null
+++ b/docs/grub-dev.texi
@@ -0,0 +1,1533 @@
+\input texinfo
+@c -*-texinfo-*-
+@c %**start of header
+@setfilename grub-dev.info
+@include version-dev.texi
+@settitle GNU GRUB Developers Manual @value{VERSION}
+@c Unify all our little indices for now.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+@c %**end of header
+
+@footnotestyle separate
+@paragraphindent 3
+@finalout
+
+@copying
+This developer manual is for GNU GRUB (version @value{VERSION},
+@value{UPDATED}).
+
+Copyright @copyright{} 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011 Free Software Foundation, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections.
+@end quotation
+@end copying
+
+@dircategory Kernel
+@direntry
+* grub-dev: (grub-dev). The GRand Unified Bootloader Dev
+@end direntry
+
+@setchapternewpage odd
+
+@titlepage
+@sp 10
+@title the GNU GRUB developer manual
+@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
+@author Yoshinori K. Okuji
+@author Colin D Bennett
+@author Vesa Jääskeläinen
+@author Colin Watson
+@author Robert Millan
+@author Carles Pina
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@c Output the table of contents at the beginning.
+@contents
+
+@finalout
+@headings double
+
+@ifnottex
+@node Top
+@top GNU GRUB developer manual
+
+This is the developer documentation of GNU GRUB, the GRand Unified Bootloader,
+a flexible and powerful boot loader program for a wide range of
+architectures.
+
+This edition documents version @value{VERSION}.
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Getting the source code::
+* Finding your way around::
+* Coding style::
+* Contributing Changes::
+* Error Handling::
+* CIA::
+* BIOS port memory map::
+* Video Subsystem::
+* PFF2 Font File Format::
+* Graphical Menu Software Design::
+* Copying This Manual:: Copying This Manual
+* Index::
+@end menu
+
+
+@node Getting the source code
+@chapter Getting the source code
+
+GRUB is maintained using the @uref{http://bazaar-vcs.org/, Bazaar revision
+control system}. To fetch the primary development branch:
+
+@example
+bzr get http://bzr.savannah.gnu.org/r/grub/trunk/grub
+@end example
+
+The GRUB developers maintain several other branches with work in progress.
+Of these, the most interesting is the experimental branch, which is a
+staging area for new code which we expect to eventually merge into trunk but
+which is not yet ready:
+
+@example
+bzr get http://bzr.savannah.gnu.org/r/grub/branches/experimental
+@end example
+
+Once you have used @kbd{bzr get} to fetch an initial copy of a branch, you
+can use @kbd{bzr pull} to keep it up to date. If you have modified your
+local version, you may need to resolve conflicts when pulling.
+
+@node Coding style
+@chapter Coding style
+@c By YoshinoriOkuji, VesaJääskeläinen and ColinBennett
+
+Basically we follow the @uref{http://www.gnu.org/prep/standards_toc.html, GNU Coding Standards}. We define additional conventions for GRUB here.
+
+@menu
+* Naming Conventions::
+* Functions::
+* Variables::
+* Types::
+* Macros::
+* Comments::
+* Multi-Line Comments::
+@end menu
+
+@node Naming Conventions
+@section Naming Conventions
+
+All global symbols (i.e. functions, variables, types, and macros) must have the prefix grub_ or GRUB_. The all capital form is used only by macros.
+
+@node Functions
+@section Functions
+
+If a function is global, its name must be prefixed with grub_ and must consist of only small letters. If the function belongs to a specific function module, the name must also be prefixed with the module name. For example, if a function is for file systems, its name is prefixed with grub_fs_. If a function is for FAT file system but not for all file systems, its name is prefixed with grub_fs_fat_. The hierarchy is noted this way.
+
+After a prefix, a function name must start with a verb (such as get or is). It must not be a noun. Some kind of abbreviation is permitted, as long as it wouldn't make code less readable (e.g. init).
+
+If a function is local, its name may not start with any prefix. It must start with a verb.
+
+@node Variables
+@section Variables
+
+The rule is mostly the same as functions, as noted above. If a variable is global, its name must be prefixed with grub_ and must consist of only small letters. If the variable belongs to a specific function module, the name must also be prefixed with the module name. For example, if a function is for dynamic loading, its name is prefixed with grub_dl_. If a variable is for ELF but not for all dynamic loading systems, its name is prefixed with grub_dl_elf_.
+
+After a prefix, a variable name must start with a noun or an adjective (such as name or long) and it should end with a noun. Some kind of abbreviation is permitted, as long as it wouldn't make code less readable (e.g. i18n).
+
+If a variable is global in the scope of a single file (i.e. it is declared with static), its name may not start with any prefix. It must start with a noun or an adjective.
+
+If a variable is local, you may choose any shorter name, as long as it wouldn't make code less readable (e.g. i).
+
+@node Types
+@section Types
+
+The name of a type must be prefixed with grub_ and must consist of only small letters. If the type belongs to a specific function module, the name must also be prefixed with the module name. For example, if a type is for OS loaders, its name is prefixed with grub_loader_. If a type is for Multiboot but not for all OS loaders, its name is prefixed with grub_loader_linux_.
+
+The name must be suffixed with _t, to emphasize the fact that it is a type but not a variable or a function.
+
+@node Macros
+@section Macros
+
+If a macro is global, its name must be prefixed with GRUB_ and must consist of only large letters. Other rules are the same as functions or variables, depending on whether a macro is used like a function or a variable.
+
+@node Comments
+@section Comments
+
+All comments shall be C-style comments, of the form @samp{/* @dots{} */}.
+
+Comments shall be placed only on a line by themselves. They shall not be placed together with code, variable declarations, or other non-comment entities. A comment should be placed immediately preceding the entity it describes.
+
+Acceptable:
+@example
+/* The page # that is the front buffer. */
+int displayed_page;
+/* The page # that is the back buffer. */
+int render_page;
+@end example
+
+Unacceptable:
+@example
+int displayed_page; /* The page # that is the front buffer. */
+int render_page; /* The page # that is the back buffer. */
+@end example
+
+@node Multi-Line Comments
+@section Multi-Line Comments
+
+Comments spanning multiple lines shall be formatted with all lines after the first aligned with the first line.
+
+Asterisk characters should not be repeated a the start of each subsequent line.
+
+Acceptable:
+@example
+/* This is a comment
+ which spans multiple lines.
+ It is long. */
+@end example
+
+Unacceptable:
+@example
+/*
+ * This is a comment
+ * which spans multiple lines.
+ * It is long. */
+@end example
+
+The opening @samp{/*} and closing @samp{*/} should be placed together on a line with text.
+
+@node Finding your way around
+@chapter Finding your way around
+
+Here is a brief map of the GRUB code base.
+
+GRUB uses Autoconf and Automake, with most of the Automake input generated
+by AutoGen. The top-level build rules are in @file{configure.ac},
+@file{grub-core/Makefile.core.def}, and @file{Makefile.util.def}. Each
+block in a @file{*.def} file represents a build target, and specifies the
+source files used to build it on various platforms. The @file{*.def} files
+are processed into AutoGen input by @file{gentpl.py} (which you only need to
+look at if you are extending the build system). If you are adding a new
+module which follows an existing pattern, such as a new command or a new
+filesystem implementation, it is usually easiest to grep
+@file{grub-core/Makefile.core.def} and @file{Makefile.util.def} for an
+existing example of that pattern to find out where it should be added.
+
+In general, code that may be run at boot time is in a subdirectory of
+@file{grub-core}, while code that is only run from within a full operating
+system is in a subdirectory of the top level.
+
+Low-level boot code, such as the MBR implementation on PC BIOS systems, is
+in the @file{grub-core/boot/} directory.
+
+The GRUB kernel is in @file{grub-core/kern/}. This contains core facilities
+such as the device, disk, and file frameworks, environment variable
+handling, list processing, and so on. The kernel should contain enough to
+get up to a rescue prompt. Header files for kernel facilities, among
+others, are in @file{include/}.
+
+Terminal implementations are in @file{grub-core/term/}.
+
+Disk access code is spread across @file{grub-core/disk/} (for accessing the
+disk devices themselves), @file{grub-core/partmap/} (for interpreting
+partition table data), and @file{grub-core/fs/} (for accessing filesystems).
+Note that, with the odd specialised exception, GRUB only contains code to
+@emph{read} from filesystems and tries to avoid containing any code to
+@emph{write} to filesystems; this lets us confidently assure users that GRUB
+cannot be responsible for filesystem corruption.
+
+PCI and USB bus handling is in @file{grub-core/bus/}.
+
+Video handling code is in @file{grub-core/video/}. The graphical menu
+system uses this heavily, but is in a separate directory,
+@file{grub-core/gfxmenu/}.
+
+Most commands are implemented by files in @file{grub-core/commands/}, with
+the following exceptions:
+
+@itemize
+@item
+A few core commands live in @file{grub-core/kern/corecmd.c}.
+
+@item
+Commands related to normal mode live under @file{grub-core/normal/}.
+
+@item
+Commands that load and boot kernels live under @file{grub-core/loader/}.
+
+@item
+The @samp{loopback} command is really a disk device, and so lives in
+@file{grub-core/disk/loopback.c}.
+
+@item
+The @samp{gettext} command lives under @file{grub-core/gettext/}.
+
+@item
+The @samp{loadfont} and @samp{lsfonts} commands live under
+@file{grub-core/font/}.
+
+@item
+The @samp{serial}, @samp{terminfo}, and @samp{background_image} commands
+live under @file{grub-core/term/}.
+
+@item
+The @samp{efiemu_*} commands live under @file{grub-core/efiemu/}.
+@end itemize
+
+There are a few other special-purpose exceptions; grep for them if they
+matter to you.
+
+Utility programs meant to be run from a full operating system are in
+@file{util/}.
+
+@node Contributing Changes
+@chapter Contributing changes
+@c By YoshinoriOkuji, VesaJääskeläinen, ColinWatson
+
+Contributing changes to GRUB 2 is welcomed activity. However we have a
+bit of control what kind of changes will be accepted to GRUB 2.
+Therefore it is important to discuss your changes on grub-devel mailing list
+(see MailingLists). On this page there are some basic details on the
+development process and activities.
+
+First of all you should come up with the idea yourself what you want to
+contribute. If you do not have that beforehand you are advised to study this
+manual and try GRUB 2 out to see what you think is missing from there.
+
+Here are additional pointers:
+@itemize
+@item @url{https://savannah.gnu.org/task/?group=grub GRUB's Task Tracker}
+@item @url{https://savannah.gnu.org/bugs/?group=grub GRUB's Bug Tracker}
+@end itemize
+
+If you intended to make changes to GRUB Legacy (<=0.97) those are not accepted
+anymore.
+
+@menu
+* Getting started::
+* Typical Developer Experience::
+* When you are approved for write access to project's files::
+@end menu
+
+@node Getting started
+@section Getting started
+
+@itemize
+@item Always use latest GRUB 2 source code. So get that first.
+
+For developers it is recommended always to use the newest development version of GRUB 2. If development takes a long period of time, please remember to keep in sync with newest developments regularly so it is much easier to integrate your change in the future. GRUB 2 is being developed in a Bazaar (bzr) repository.
+
+Please check Savannah's GRUB project page for details how to get newest bzr:
+@uref{http://savannah.gnu.org/bzr/?group=grub, GRUB 2 bzr Repository}
+
+@item Compile it and try it out.
+
+It is always good idea to first see that things work somehow and after that
+to start to implement new features or develop fixes to bugs.
+
+@item Study the code.
+
+There are sometimes odd ways to do things in GRUB 2 code base.
+This is mainly related to limited environment where GRUB 2 is being executed.
+You usually do not need to understand it all so it is better to only try to
+look at places that relates to your work. Please do not hesitate to ask for
+help if there is something that you do not understand.
+
+@item Develop a new feature.
+
+Now that you know what to do and how it should work in GRUB 2 code base, please
+be free to develop it. If you have not so far announced your idea on grub-devel
+mailing list, please do it now. This is to make sure you are not wasting your
+time working on the solution that will not be integrated to GRUB 2 code base.
+
+You might want to study our coding style before starting development so you
+do not need to change much of the code when your patch is being reviewed.
+(see @ref{Coding style})
+
+For every accepted patch there has to exist a ChangeLog entry. Our ChangeLog
+consist of changes within source code and are not describing about what the
+change logically does. Please see examples from previous entries.
+
+Also remember that GRUB 2 is licensed under GPLv3 license and that usually
+means that you are not allowed to copy pieces of code from other projects.
+Even if the source project's license would be compatible with GPLv3, please
+discuss it beforehand on grub-devel mailing list.
+
+@item Test your change.
+
+Test that your change works properly. Try it out a couple of times, preferably on different systems, and try to find problems with it.
+
+@item Publish your change.
+
+When you are happy with your change, first make sure it is compilable with
+latest development version of GRUB 2. After that please send a patch to
+grub-devel for review. Please describe in your email why you made the change,
+what it changes and so on. Please be prepared to receive even discouraging
+comments about your patch. There is usually at least something that needs
+to be improved in every patch.
+
+Please use unified diff to make your patch (good match of arguments for diff is @samp{-pruN}).
+
+@item Respond to received feedback.
+
+If you are asked to modify your patch, please do that and resubmit it for
+review. If your change is large you are required to submit a copyright
+agreement to FSF. Please keep in mind that if you are asked to submit
+for copyright agreement, process can take some time and is mandatory
+in order to get your changes integrated.
+
+If you are not on grub-devel to respond to questions, most likely your patch
+will not be accepted. Also if problems arise from your changes later on,
+it would be preferable that you also fix the problem. So stay around
+for a while.
+
+@item Your patch is accepted.
+
+Good job! Your patch will now be integrated into GRUB 2 mainline, and if it didn't break anything it will be publicly available in the next release.
+
+Now you are welcome to do further improvements :)
+@end itemize
+
+@node Typical Developer Experience
+@section Typical Developer Experience
+
+The typical experience for a developer in this project is the following:
+
+@enumerate
+@item You find yourself wanting to do something (e.g. fixing a bug).
+@item You show some result in the mailing list or the IRC.
+@item You are getting to be known to other developers.
+@item You accumulate significant amount of contribution, so copyright assignment is processed.
+@item You are free to check in your changes on your own, legally speaking.
+@end enumerate
+
+At this point, it is rather annoying that you ought to ask somebody else every
+change to be checked in. For efficiency, it is far better, if you can commit
+it yourself. Therefore, our policy is to give you the write permission to our
+official repository, once you have shown your skill and will,
+and the FSF clerks have dealt with your copyright assignment.
+
+@node When you are approved for write access to project's files
+@section When you are approved for write access to project's files
+
+As you might know, GRUB is hosted on
+@url{https://savannah.gnu.org/projects/grub Savannah}, thus the membership
+is managed by Savannah. This means that, if you want to be a member of this
+project:
+
+@enumerate
+@item You need to create your own account on Savannah.
+@item You can submit ``Request for Inclusion'' from ``My Groups'' on Savannah.
+@end enumerate
+
+Then, one of the admins can approve your request, and you will be a member.
+If you don't want to use the Savannah interface to submit a request, you can
+simply notify the admins by email or something else, alternatively. But you
+still need to create an account beforehand.
+
+NOTE: we sometimes receive a ``Request for Inclusion'' from an unknown person.
+In this case, the request would be just discarded, since it is too dangerous
+to allow a stranger to be a member, which automatically gives him a commit
+right to the repository, both for a legal reason and for a technical reason.
+
+If your intention is to just get started, please do not submit a inclusion
+request. Instead, please subscribe to the mailing list, and communicate first
+(e.g. sending a patch, asking a question, commenting on another message...).
+
+@node Error Handling
+@chapter Error Handling
+
+Error handling in GRUB 2 is based on exception handling model. As C language
+doesn't directly support exceptions, exception handling behavior is emulated
+in software.
+
+When exception is raised, function must return to calling function. If calling
+function does not provide handling of the exception it must return back to its
+calling function and so on, until exception is handled. If exception is not
+handled before prompt is displayed, error message will be shown to user.
+
+Exception information is stored on @code{grub_errno} global variable. If
+@code{grub_errno} variable contains value @code{GRUB_ERR_NONE}, there is no active
+exception and application can continue normal processing. When @code{grub_errno} has
+other value, it is required that application code either handles this error or
+returns instantly to caller. If function is with return type @code{grub_err_t} is
+about to return @code{GRUB_ERR_NONE}, it should not set @code{grub_errno} to that
+value. Only set @code{grub_errno} in cases where there is error situation.
+
+Simple exception forwarder.
+@example
+grub_err_t
+forwarding_example (void)
+@{
+ /* Call function that might cause exception. */
+ foobar ();
+
+ /* No special exception handler, just forward possible exceptions. */
+ if (grub_errno != GRUB_ERR_NONE)
+ @{
+ return grub_errno;
+ @}
+
+ /* All is OK, do more processing. */
+
+ /* Return OK signal, to caller. */
+ return GRUB_ERR_NONE;
+@}
+@end example
+
+Error reporting has two components, the actual error code (of type
+@code{grub_err_t}) and textual message that will be displayed to user. List of
+valid error codes is listed in header file @file{include/grub/err.h}. Textual
+error message can contain any textual data. At time of writing, error message
+can contain up to 256 characters (including terminating NUL). To ease error
+reporting there is a helper function @code{grub_error} that allows easier
+formatting of error messages and should be used instead of writing directly to
+global variables.
+
+Example of error reporting.
+@example
+grub_err_t
+failing_example ()
+@{
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+ "Failed to read %s, tried %d times.",
+ "test.txt",
+ 10);
+@}
+@end example
+
+If there is a special reason that error code does not need to be taken account,
+@code{grub_errno} can be zeroed back to @code{GRUB_ERR_NONE}. In cases like this all
+previous error codes should have been handled correctly. This makes sure that
+there are no unhandled exceptions.
+
+Example of zeroing @code{grub_errno}.
+@example
+grub_err_t
+probe_example ()
+@{
+ /* Try to probe device type 1. */
+ probe_for_device ();
+ if (grub_errno == GRUB_ERR_NONE)
+ @{
+ /* Device type 1 was found on system. */
+ register_device ();
+ return GRUB_ERR_NONE;
+ @}
+ /* Zero out error code. */
+ grub_errno = GRUB_ERR_NONE;
+
+ /* No device type 1 found, try to probe device type 2. */
+ probe_for_device2 ();
+ if (grub_errno == GRUB_ERR_NONE)
+ @{
+ /* Device type 2 was found on system. */
+ register_device2 ();
+ return GRUB_ERR_NONE;
+ @}
+ /* Zero out error code. */
+ grub_errno = GRUB_ERR_NONE;
+
+ /* Return custom error message. */
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No device type 1 or 2 found.");
+@}
+@end example
+
+Some times there is a need to continue processing even if there is a error
+state in application. In situations like this, there is a needed to save old
+error state and then call other functions that might fail. To aid in this,
+there is a error stack implemented. Error state can be pushed to error stack
+by calling function @code{grub_error_push ()}. When processing has been completed,
+@code{grub_error_pop ()} can be used to pop error state from stack. Error stack
+contains predefined amount of error stack items. Error stack is protected for
+overflow and marks these situations so overflow error does not get unseen.
+If there is no space available to store error message, it is simply discarded
+and overflow will be marked as happened. When overflow happens, it most likely
+will corrupt error stack consistency as for pushed error there is no matching
+pop, but overflow message will be shown to inform user about the situation.
+Overflow message will be shown at time when prompt is about to be drawn.
+
+Example usage of error stack.
+@example
+/* Save possible old error message. */
+grub_error_push ();
+
+/* Do your stuff here. */
+call_possibly_failing_function ();
+
+if (grub_errno != GRUB_ERR_NONE)
+ @{
+ /* Inform rest of the code that there is error (grub_errno
+ is set). There is no pop here as we want both error states
+ to be displayed. */
+ return;
+ @}
+
+/* Restore old error state by popping previous item from stack. */
+grub_error_pop ();
+@end example
+
+@node CIA
+@chapter CIA
+@c By Robert Millan and Carles Pina
+If you have commit access, please setup CIA in your Bazaar
+config so those in IRC receive notification of your commits.
+
+In @file{~/.bazaar/bazaar.conf}, add "cia_send_revno = true".
+Optionally, you can also add "cia_user = myusername" if you'd
+like CIA service to use a specific account (for statistical purpose).
+
+In the @file{.bzr/branch/branch.conf} of your checkout branch,
+"set nickname = /path_to_this_branch" and "cia_project = GNU GRUB".
+
+Additionally, please set cia_send_revno in the [DEFAULT] section
+of your @file{~/.bazaar/bazaar.conf}. E.g.:
+
+@example
+[DEFAULT]
+cia_send_revno = true
+@end example
+
+Remember to install cia-clients (Debian/Ubuntu package) to be able to use CIA.
+
+Keep in mind Bazaar sends notifications for all commits to branches that have
+this setting, regardless of whether they're bound branches (checkouts) or not.
+So if you make local commits in a non-bound branch and it bothers you that
+others can read them, do not use this setting.
+
+@node BIOS port memory map
+@chapter BIOS port memory map
+@c By Yoshinori K Okuji
+
+@multitable @columnfractions .15 .25 .5
+@headitem Start @tab End @tab Usage
+@item 0 @tab 0x1000 - 1 @tab BIOS and real mode interrupts
+@item 0x07BE @tab 0x07FF @tab Partition table passed to another boot loader
+@item ? @tab 0x2000 - 1 @tab Real mode stack
+@item 0x7C00 @tab 0x7D00 - 1 @tab Boot sector
+@item 0x8000 @tab ? @tab GRUB kernel
+@item 0x68000 @tab 0x78000 - 1 @tab Disk buffer
+@item ? @tab 0x80000 - 1 @tab Protected mode stack
+@item 0x80000 @tab ? @tab Heap
+@item ? @tab 0xA0000 - 1 @tab Extended BIOS Data Area
+@item 0xA0000 @tab 0xC0000 - 1 @tab Video RAM
+@item 0xC0000 @tab 0x100000 - 1 @tab BIOS
+@item 0x100000 @tab ? @tab Heap and module code
+@end multitable
+
+@node Video Subsystem
+@chapter Video Subsystem
+@c By VesaJääskeläinen
+This document contains specification for Video Subsystem for GRUB2.
+Currently only the usage interface is described in this document.
+Internal structure of how video drivers are registering and how video
+driver manager works are not included here.
+
+@menu
+* Video API::
+* Bitmap API::
+* Example usage of Video API::
+@end menu
+
+@node Video API
+@section Video API
+
+@subsection grub_video_setup
+
+@itemize
+@item Prototype:
+@example
+grub_err_t
+grub_video_setup (unsigned int width, unsigned int height, unsigned int mode_type);
+@end example
+@item Description:
+
+Driver will use information provided to it to select best possible video mode and switch to it. Supported values for @code{mode_type} are @code{GRUB_VIDEO_MODE_TYPE_INDEX_COLOR} for index color modes, @code{GRUB_VIDEO_MODE_TYPE_RGB} for direct RGB color modes and @code{GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED} for double buffering. When requesting RGB mode, highest bits per pixel mode will be selected. When requesting Index color mode, mode with highest number of colors will be selected. If all parameters are specified as zero, video adapter will try to figure out best possible mode and initialize it, platform specific differences are allowed here. If there is no mode matching request, error X will be returned. If there are no problems, function returns @code{GRUB_ERR_NONE}.
+
+This function also performs following task upon succesful mode switch. Active rendering target is changed to screen and viewport is maximized to allow whole screen to be used when performing graphics operations. In RGB modes, emulated palette gets 16 entries containing default values for VGA palette, other colors are defined as black. When switching to Indexed Color mode, driver may set default VGA palette to screen if the video card allows the operation.
+
+@end itemize
+
+@subsection grub_video_restore
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_restore (void);
+@end example
+@item Description:
+
+Video subsystem will deinitialize activated video driver to restore old state of video device. This can be used to switch back to text mode.
+@end itemize
+
+@subsection grub_video_get_info
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_get_info (struct grub_video_mode_info *mode_info);
+@end example
+@example
+struct grub_video_mode_info
+@{
+ /* Width of the screen. */
+ unsigned int width;
+ /* Height of the screen. */
+ unsigned int height;
+ /* Mode type bitmask. Contains information like is it Index color or
+ RGB mode. */
+ unsigned int mode_type;
+ /* Bits per pixel. */
+ unsigned int bpp;
+ /* Bytes per pixel. */
+ unsigned int bytes_per_pixel;
+ /* Pitch of one scanline. How many bytes there are for scanline. */
+ unsigned int pitch;
+ /* In index color mode, number of colors. In RGB mode this is 256. */
+ unsigned int number_of_colors;
+ /* Optimization hint how binary data is coded. */
+ enum grub_video_blit_format blit_format;
+ /* How many bits are reserved for red color. */
+ unsigned int red_mask_size;
+ /* What is location of red color bits. In Index Color mode, this is 0. */
+ unsigned int red_field_pos;
+ /* How many bits are reserved for green color. */
+ unsigned int green_mask_size;
+ /* What is location of green color bits. In Index Color mode, this is 0. */
+ unsigned int green_field_pos;
+ /* How many bits are reserved for blue color. */
+ unsigned int blue_mask_size;
+ /* What is location of blue color bits. In Index Color mode, this is 0. */
+ unsigned int blue_field_pos;
+ /* How many bits are reserved in color. */
+ unsigned int reserved_mask_size;
+ /* What is location of reserved color bits. In Index Color mode,
+ this is 0. */
+ unsigned int reserved_field_pos;
+@};
+@end example
+@item Description:
+
+Software developer can use this function to query properties of active rendering taget. Information provided here can be used by other parts of GRUB, like image loaders to convert loaded images to correct screen format to allow more optimized blitters to be used. If there there is no configured video driver with active screen, error @code{GRUB_ERR_BAD_DEVICE} is returned, otherwise @code{mode_info} is filled with valid information and @code{GRUB_ERR_NONE} is returned.
+@end itemize
+
+@subsection grub_video_get_blit_format
+@itemize
+@item Prototype:
+
+@example
+enum grub_video_blit_format
+grub_video_get_blit_format (struct grub_video_mode_info *mode_info);
+@end example
+@example
+enum grub_video_blit_format
+ @{
+ /* Follow exactly field & mask information. */
+ GRUB_VIDEO_BLIT_FORMAT_RGBA,
+ /* Make optimization assumption. */
+ GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8,
+ /* Follow exactly field & mask information. */
+ GRUB_VIDEO_BLIT_FORMAT_RGB,
+ /* Make optimization assumption. */
+ GRUB_VIDEO_BLIT_FORMAT_R8G8B8,
+ /* When needed, decode color or just use value as is. */
+ GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR
+ @};
+@end example
+@item Description:
+
+Used to query how data could be optimized to suit specified video mode. Returns exact video format type, or a generic one if there is no definition for the type. For generic formats, use @code{grub_video_get_info} to query video color coding settings.
+@end itemize
+
+@subsection grub_video_set_palette
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data);
+@end example
+@example
+struct grub_video_palette_data
+@{
+ grub_uint8_t r; /* Red color value (0-255). */
+ grub_uint8_t g; /* Green color value (0-255). */
+ grub_uint8_t b; /* Blue color value (0-255). */
+ grub_uint8_t a; /* Reserved bits value (0-255). */
+@};
+@end example
+@item Description:
+
+Used to setup indexed color palettes. If mode is RGB mode, colors will be set to emulated palette data. In Indexed Color modes, palettes will be set to hardware. Color values will be converted to suit requirements of the video mode. @code{start} will tell what hardware color index (or emulated color index) will be set to according information in first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been set.
+@end itemize
+
+@subsection grub_video_get_palette
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_get_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data);
+@end example
+@example
+struct grub_video_palette_data
+@{
+ grub_uint8_t r; /* Red color value (0-255). */
+ grub_uint8_t g; /* Green color value (0-255). */
+ grub_uint8_t b; /* Blue color value (0-255). */
+ grub_uint8_t a; /* Reserved bits value (0-255). */
+@};
+@end example
+@item Description:
+
+Used to query indexed color palettes. If mode is RGB mode, colors will be copied from emulated palette data. In Indexed Color modes, palettes will be read from hardware. Color values will be converted to suit structure format. @code{start} will tell what hardware color index (or emulated color index) will be used as a source for first indice of @code{palette_data}, after that both hardware color index and @code{palette_data} index will be incremented until @code{count} number of colors have been read.
+@end itemize
+
+@subsection grub_video_set_viewport
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_set_viewport (unsigned int x, unsigned int y, unsigned int width, unsigned int height);
+@end example
+@item Description:
+
+Used to specify viewport where draw commands are performed. When viewport is set, all draw commands coordinates relate to those specified by @code{x} and @code{y}. If draw commands try to draw over viewport, they are clipped. If developer requests larger than possible viewport, width and height will be clamped to fit screen. If @code{x} and @code{y} are out of bounds, all functions drawing to screen will not be displayed. In order to maximize viewport, use @code{grub_video_get_info} to query actual screen dimensions and provide that information to this function.
+@end itemize
+
+@subsection grub_video_get_viewport
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_get_viewport (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height);
+@end example
+@item Description:
+
+Used to query current viewport dimensions. Software developer can use this to choose best way to render contents of the viewport.
+@end itemize
+
+@subsection grub_video_map_color
+@itemize
+@item Prototype:
+
+@example
+grub_video_color_t
+grub_video_map_color (grub_uint32_t color_name);
+@end example
+@item Description:
+
+Map color can be used to support color themes in GRUB. There will be collection of color names that can be used to query actual screen mapped color data. Examples could be @code{GRUB_COLOR_CONSOLE_BACKGROUND}, @code{GRUB_COLOR_CONSOLE_TEXT}. The actual color defines are not specified at this point.
+@end itemize
+
+@subsection grub_video_map_rgb
+@itemize
+@item Prototype:
+
+@example
+grub_video_color_t
+grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue);
+@end example
+@item Description:
+
+Map RGB values to compatible screen color data. Values are expected to be in range 0-255 and in RGB modes they will be converted to screen color data. In index color modes, index color palette will be searched for specified color and then index is returned.
+@end itemize
+
+@subsection grub_video_map_rgba
+@itemize
+@item Prototype:
+
+@example
+grub_video_color_t
+grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue, grub_uint8_t alpha);
+@end example
+@item Description:
+
+Map RGBA values to compatible screen color data. Values are expected to be in range 0-255. In RGBA modes they will be converted to screen color data. In index color modes, index color palette will be searched for best matching color and its index is returned.
+@end itemize
+
+@subsection grub_video_unmap_color
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red, grub_uint8_t *green, grub_uint8_t *blue, grub_uint8_t *alpha);
+@end example
+@item Description:
+
+Unmap color value from @code{color} to color channels in @code{red}, @code{green}, @code{blue} and @code{alpha}. Values will be in range 0-255. Active rendering target will be used for color domain. In case alpha information is not available in rendering target, it is assumed to be opaque (having value 255).
+@end itemize
+
+@subsection grub_video_fill_rect
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_fill_rect (grub_video_color_t color, int x, int y, unsigned int width, unsigned int height);
+@end example
+@item Description:
+
+Fill specified area limited by given coordinates within specified viewport. Negative coordinates are accepted in order to allow easy moving of rectangle within viewport. If coordinates are negative, area of the rectangle will be shrinken to follow size limits of the viewport.
+
+Software developer should use either @code{grub_video_map_color}, @code{grub_video_map_rgb} or @code{grub_video_map_rgba} to map requested color to @code{color} parameter.
+@end itemize
+
+@subsection grub_video_blit_glyph
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_blit_glyph (struct grub_font_glyph *glyph, grub_video_color_t color, int x, int y);
+@end example
+@example
+struct grub_font_glyph @{
+ /* TBD. */
+@};
+@end example
+@item Description:
+
+Used to blit glyph to viewport in specified coodinates. If glyph is at edge of viewport, pixels outside of viewport will be clipped out. Software developer should use either @code{grub_video_map_rgb} or @code{grub_video_map_rgba} to map requested color to @code{color} parameter.
+@end itemize
+
+@subsection grub_video_blit_bitmap
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, unsigned int width, unsigned int height);
+@end example
+@example
+struct grub_video_bitmap
+@{
+ /* TBD. */
+@};
+
+enum grub_video_blit_operators
+ @{
+ GRUB_VIDEO_BLIT_REPLACE,
+ GRUB_VIDEO_BLIT_BLEND
+ @};
+@end example
+@item Description:
+
+Used to blit bitmap to viewport in specified coordinates. If part of bitmap is outside of viewport region, it will be clipped out. Offsets affect bitmap position where data will be copied from. Negative values for both viewport coordinates and bitmap offset coordinates are allowed. If data is looked out of bounds of bitmap, color value will be assumed to be transparent. If viewport coordinates are negative, area of the blitted rectangle will be shrinken to follow size limits of the viewport and bitmap. Blitting operator @code{oper} specifies should source pixel replace data in screen or blend with pixel alpha value.
+
+Software developer should use @code{grub_video_bitmap_create} or @code{grub_video_bitmap_load} to create or load bitmap data.
+@end itemize
+
+@subsection grub_video_blit_render_target
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_blit_render_target (struct grub_video_render_target *source, enum grub_video_blit_operators oper, int x, int y, int offset_x, int offset_y, unsigned int width, unsigned int height);
+@end example
+@example
+struct grub_video_render_target @{
+ /* This is private data for video driver. Should not be accessed from elsewhere directly. */
+@};
+
+enum grub_video_blit_operators
+ @{
+ GRUB_VIDEO_BLIT_REPLACE,
+ GRUB_VIDEO_BLIT_BLEND
+ @};
+@end example
+@item Description:
+
+Used to blit source render target to viewport in specified coordinates. If part of source render target is outside of viewport region, it will be clipped out. If blitting operator is specified and source contains alpha values, resulting pixel color components will be calculated using formula ((src_color * src_alpha) + (dst_color * (255 - src_alpha)) / 255, if target buffer has alpha, it will be set to src_alpha. Offsets affect render target position where data will be copied from. If data is looked out of bounds of render target, color value will be assumed to be transparent. Blitting operator @code{oper} specifies should source pixel replace data in screen or blend with pixel alpha value.
+@end itemize
+
+@subsection grub_video_scroll
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_scroll (grub_video_color_t color, int dx, int dy);
+@end example
+@item Description:
+
+Used to scroll viewport to specified direction. New areas are filled with specified color. This function is used when screen is scroller up in video terminal.
+@end itemize
+
+@subsection grub_video_swap_buffers
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_swap_buffers (void);
+@end example
+@item Description:
+
+If double buffering is enabled, this swaps frontbuffer and backbuffer, in order to show values drawn to back buffer. Video driver is free to choose how this operation is techincally done.
+@end itemize
+
+@subsection grub_video_create_render_target
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_create_render_target (struct grub_video_render_target **result, unsigned int width, unsigned int height, unsigned int mode_type);
+@end example
+@example
+struct grub_video_render_target @{
+ /* This is private data for video driver. Should not be accessed from elsewhere directly. */
+@};
+@end example
+@item Description:
+
+Driver will use information provided to it to create best fitting render target. @code{mode_type} will be used to guide on selecting what features are wanted for render target. Supported values for @code{mode_type} are @code{GRUB_VIDEO_MODE_TYPE_INDEX_COLOR} for index color modes, @code{GRUB_VIDEO_MODE_TYPE_RGB} for direct RGB color modes and @code{GRUB_VIDEO_MODE_TYPE_ALPHA} for alpha component.
+@end itemize
+
+@subsection grub_video_delete_render_target
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_delete_render_target (struct grub_video_render_target *target);
+@end example
+@item Description:
+
+Used to delete previously created render target. If @code{target} contains @code{NULL} pointer, nothing will be done. If render target is correctly destroyed, GRUB_ERR_NONE is returned.
+@end itemize
+
+@subsection grub_video_set_active_render_target
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_set_active_render_target (struct grub_video_render_target *target);
+@end example
+@item Description:
+
+Sets active render target. If this comand is successful all drawing commands will be done to specified @code{target}. There is also special values for target, @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY} used to reference screen's front buffer, @code{GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER} used to reference screen's front buffer (alias for @code{GRUB_VIDEO_RENDER_TARGET_DISPLAY}) and @code{GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER} used to reference back buffer (if double buffering is enabled). If render target is correclty switched GRUB_ERR_NONE is returned. In no any event shall there be non drawable active render target.
+
+@end itemize
+@subsection grub_video_get_active_render_target
+@itemize
+@item Prototype:
+
+@example
+grub_err_t
+grub_video_get_active_render_target (struct grub_video_render_target **target);
+@end example
+@item Description:
+
+Returns currently active render target. It returns value in @code{target} that can be subsequently issued back to @code{grub_video_set_active_render_target}.
+@end itemize
+
+@node Example usage of Video API
+@section Example usage of Video API
+@subsection Example of screen setup
+@example
+grub_err_t rc;
+/* Try to initialize video mode 1024 x 768 with direct RGB. */
+rc = grub_video_setup (1024, 768, GRUB_VIDEO_MODE_TYPE_RGB);
+if (rc != GRUB_ERR_NONE)
+@{
+ /* Fall back to standard VGA Index Color mode. */
+ rc = grub_video_setup (640, 480, GRUB_VIDEO_MODE_TYPE_INDEX);
+ if (rc != GRUB_ERR_NONE)
+ @{
+ /* Handle error. */
+ @}
+@}
+@end example
+@subsection Example of setting up console viewport
+@example
+grub_uint32_t x, y, width, height;
+grub_video_color_t color;
+struct grub_font_glyph glyph;
+grub_err_t rc;
+/* Query existing viewport. */
+grub_video_get_viewport (&x, &y, &width, &height);
+/* Fill background. */
+color = grub_video_map_color (GRUB_COLOR_BACKGROUND);
+grub_video_fill_rect (color, 0, 0, width, height);
+/* Setup console viewport. */
+grub_video_set_viewport (x + 10, y + 10, width - 20, height - 20);
+grub_video_get_viewport (&x, &y, &width, &height);
+color = grub_video_map_color (GRUB_COLOR_CONSOLE_BACKGROUND);
+grub_video_fill_rect (color, 0, 0, width, height);
+/* Draw text to viewport. */
+color = grub_video_map_color (GRUB_COLOR_CONSOLE_TEXT);
+grub_font_get_glyph ('X', &glyph);
+grub_video_blit_glyph (&glyph, color, 0, 0);
+@end example
+
+@node Bitmap API
+@section Bitmap API
+@itemize
+@subsection grub_video_bitmap_create
+@item Prototype:
+@example
+grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap, unsigned int width, unsigned int height, enum grub_video_blit_format blit_format)
+@end example
+
+@item Description:
+
+Creates a new bitmap with given dimensions and blitting format. Allocated bitmap data can then be modified freely and finally blitted with @code{grub_video_blit_bitmap} to rendering target.
+@end itemize
+
+@subsection grub_video_bitmap_destroy
+@itemize
+@item Prototype:
+@example
+grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap);
+@end example
+
+@item Description:
+
+When bitmap is no longer needed, it can be freed from memory using this command. @code{bitmap} is previously allocated bitmap with @code{grub_video_bitmap_create} or loaded with @code{grub_video_bitmap_load}.
+@end itemize
+
+@subsection grub_video_bitmap_load
+@itemize
+@item Prototype:
+@example
+grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap, const char *filename);
+@end example
+
+@item Description:
+
+Tries to load given bitmap (@code{filename}) using registered bitmap loaders. In case bitmap format is not recognized or supported error @code{GRUB_ERR_BAD_FILE_TYPE} is returned.
+@end itemize
+
+@subsection grub_video_bitmap_get_width
+@itemize
+@item Prototype:
+@example
+unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap);
+@end example
+
+@item Description:
+
+Returns bitmap width.
+@end itemize
+
+@subsection grub_video_bitmap_get_height
+@itemize
+@item Prototype:
+@example
+unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap);
+@end example
+
+@item Description:
+
+Return bitmap height.
+@end itemize
+
+@subsection grub_video_bitmap_get_mode_info
+@itemize
+@item Prototype:
+@example
+void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, struct grub_video_mode_info *mode_info);
+@end example
+
+@item Description:
+
+Returns bitmap format details in form of @code{grub_video_mode_info}.
+@end itemize
+
+@subsection grub_video_bitmap_get_data
+@itemize
+@item Prototype:
+@example
+void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap);
+@end example
+
+@item Description:
+
+Return pointer to bitmap data. Contents of the pointed data can be freely modified. There is no extra protection against going off the bounds so you have to be carefull how to access the data.
+@end itemize
+
+@node PFF2 Font File Format
+@chapter PFF2 Font File Format
+
+@c Author: Colin D. Bennett <colin@gibibit.com>
+@c Date: 8 January 2009
+
+@menu
+* Introduction::
+* File Structure::
+* Font Metrics::
+@end menu
+
+
+@node Introduction
+@section Introduction
+
+The goal of this format is to provide a bitmap font format that is simple to
+use, compact, and cleanly supports Unicode.
+
+
+@subsection Goals of the GRUB Font Format
+
+@itemize
+@item Simple to read and use.
+Since GRUB will only be reading the font files,
+we are more concerned with making the code to read the font simple than we
+are with writing the font.
+
+@item Compact storage.
+The fonts will generally be stored in a small boot
+partition where GRUB is located, and this may be on a removable storage
+device such as a CD or USB flash drive where space is more limited than it
+is on most hard drives.
+
+@item Unicode.
+GRUB should not have to deal with multiple character
+encodings. The font should always use Unicode character codes for simple
+internationalization.
+@end itemize
+
+@subsection Why Another Font Format?
+
+There are many existing bitmap font formats that GRUB could use. However,
+there are aspects of these formats that may make them less than suitable for
+use in GRUB at this time:
+
+@table @samp
+@item BDF
+Inefficient storage; uses ASCII to describe properties and
+hexadecimal numbers in ASCII for the bitmap rows.
+@item PCF
+Many format variations such as byte order and bitmap padding (rows
+padded to byte, word, etc.) would result in more complex code to
+handle the font format.
+@end table
+
+@node File Structure
+@section File Structure
+
+A file @strong{section} consists of a 4-byte name, a 32-bit big-endian length (not
+including the name or length), and then @var{length} more section-type-specific
+bytes.
+
+The standard file extension for PFF2 font files is @file{.pf2}.
+
+
+@subsection Section Types
+
+@table @samp
+@item FILE
+@strong{File type ID} (ASCII string). This must be the first section in the file. It has length 4
+and the contents are the four bytes of the ASCII string @samp{PFF2}.
+
+@item NAME
+@strong{Font name} (ASCII string). This is the full font name including family,
+weight, style, and point size. For instance, "Helvetica Bold Italic 14".
+
+@item FAMI
+@strong{Font family name} (ASCII string). For instance, "Helvetica". This should
+be included so that intelligent font substitution can take place.
+
+@item WEIG
+@strong{Font weight} (ASCII string). Valid values are @samp{bold} and @samp{normal}.
+This should be included so that intelligent font substitution can take
+place.
+
+@item SLAN
+@strong{Font slant} (ASCII string). Valid values are @samp{italic} and @samp{normal}.
+This should be included so that intelligent font substitution can take
+place.
+
+@item PTSZ
+@strong{Font point size} (uint16be).
+
+@item MAXW
+@strong{Maximum character width in pixels} (uint16be).
+
+@item MAXH
+@strong{Maximum character height in pixels} (uint16be).
+
+@item ASCE
+@strong{Ascent in pixels} (uint16be). @xref{Font Metrics}, for details.
+
+@item DESC
+@strong{Descent in pixels} (uint16be). @xref{Font Metrics}, for details.
+
+@item CHIX
+@strong{Character index.}
+The character index begins with a 32-bit big-endian unsigned integer
+indicating the total size of the section, not including this size value.
+For each character, there is an instance of the following entry structure:
+
+@itemize
+@item @strong{Unicode code point.} (32-bit big-endian integer.)
+
+@item @strong{Storage flags.} (byte.)
+
+@itemize
+@item Bits 2..0:
+
+If equal to 000 binary, then the character data is stored
+uncompressed beginning at the offset indicated by the character's
+@strong{offset} value.
+
+If equal to 001 binary, then the character data is stored within a
+compressed character definition block that begins at the offset
+within the file indicated by the character's @strong{offset} value.
+@end itemize
+
+@item @strong{Offset.} (32-bit big-endian integer.)
+
+A marker that indicates the remainder of the file is data accessed via
+the character index (CHIX) section. When reading this font file, the rest
+of the file can be ignored when scanning the sections. The length should
+be set to -1 (0xFFFFFFFF).
+
+Supported data structures:
+
+Character definition
+Each character definition consists of:
+
+@itemize
+@item @strong{Width.}
+Width of the bitmap in pixels. The bitmap's extents
+represent the glyph's bounding box. @code{uint16be}.
+
+@item @strong{Height.}
+Height of the bitmap in pixels. The bitmap's extents
+represent the glyph's bounding box. @code{uint16be}.
+
+@item @strong{X offset.}
+The number of pixels to shift the bitmap by
+horizontally before drawing the character. @code{int16be}.
+
+@item @strong{Y offset.}
+The number of pixels to shift the bitmap by
+vertically before drawing the character. @code{int16be}.
+
+@item @strong{Device width.}
+The number of pixels to advance horizontally from
+this character's origin to the origin of the next character.
+@code{int16be}.
+
+@item @strong{Bitmap data.}
+This is encoded as a string of bits. It is
+organized as a row-major, top-down, left-to-right bitmap. The most
+significant bit of each byte is taken to be the leftmost or uppermost
+bit in the byte. For the sake of compact storage, rows are not padded
+to byte boundaries (i.e., a single byte may contain bits belonging to
+multiple rows). The last byte of the bitmap @strong{is} padded with zero
+bits in the bits positions to the right of the last used bit if the
+bitmap data does not fill the last byte.
+
+The length of the @strong{bitmap data} field is (@var{width} * @var{height} + 7) / 8
+using integer arithmetic, which is equivalent to ceil(@var{width} *
+@var{height} / 8) using real number arithmetic.
+
+It remains to be determined whether bitmap fonts usually make all
+glyph bitmaps the same height, or if smaller glyphs are stored with
+bitmaps having a lesser height. In the latter case, the baseline
+would have to be used to calculate the location the bitmap should be
+anchored at on screen.
+@end itemize
+
+@end itemize
+@end table
+
+@node Font Metrics
+@section Font Metrics
+
+@itemize
+@item Ascent.
+The distance from the baseline to the top of most characters.
+Note that in some cases characters may extend above the ascent.
+
+@item Descent.
+The distance from the baseline to the bottom of most characters. Note that
+in some cases characters may extend below the descent.
+
+@item Leading.
+The amount of space, in pixels, to leave between the descent of one line of
+text and the ascent of the next line. This metrics is not specified in the
+current file format; instead, the font rendering engine calculates a
+reasonable leading value based on the other font metrics.
+
+@item Horizonal leading.
+The amount of space, in pixels, to leave horizontally between the left and
+right edges of two adjacent glyphs. The @strong{device width} field determines
+the effective leading value that is used to render the font.
+
+@end itemize
+@image{font_char_metrics,,,,.png}
+
+An illustration of how the various font metrics apply to characters.
+
+
+
+@node Graphical Menu Software Design
+@chapter Graphical Menu Software Design
+
+@c By Colin D. Bennett <colin@gibibit.com>
+@c Date: 17 August 2008
+
+@menu
+* Introduction_2::
+* Startup Sequence::
+* GUI Components::
+* Command Line Window::
+@end menu
+
+@node Introduction_2
+@section Introduction
+
+The @samp{gfxmenu} module provides a graphical menu interface for GRUB 2. It
+functions as an alternative to the menu interface provided by the @samp{normal}
+module, which uses the grub terminal interface to display a menu on a
+character-oriented terminal.
+
+The graphical menu uses the GRUB video API, which is currently for the VESA
+BIOS extensions (VBE) 2.0+. This is supported on the i386-pc platform.
+However, the graphical menu itself does not depend on using VBE, so if another
+GRUB video driver were implemented, the @samp{gfxmenu} graphical menu would work
+on the new video driver as well.
+
+
+@node Startup Sequence
+@section Startup Sequence
+
+@itemize
+@item grub_enter_normal_mode [normal/main.c]
+@item grub_normal_execute [normal/main.c]
+@item read_config_file [normal/main.c]
+@item (When @file{gfxmenu.mod} is loaded with @command{insmod}, it will call @code{grub_menu_viewer_register()} to register itself.)
+@item GRUB_MOD_INIT (gfxmenu) [gfxmenu/gfxmenu.c]
+@item grub_menu_viewer_register [kern/menu_viewer.c]
+@item grub_menu_viewer_show_menu [kern/menu_viewer.c]
+@item get_current_menu_viewer() [kern/menu_viewer.c]
+@item show_menu() [gfxmenu/gfxmenu.c]
+@item grub_gfxmenu_model_new [gfxmenu/model.c]
+@item grub_gfxmenu_view_new [gfxmenu/view.c]
+@item set_graphics_mode [gfxmenu/view.c]
+@item grub_gfxmenu_view_load_theme [gfxmenu/theme_loader.c]
+@end itemize
+
+
+@node GUI Components
+@section GUI Components
+
+The graphical menu implements a GUI component system that supports a
+container-based layout system. Components can be added to containers, and
+containers (which are a type of component) can then be added to other
+containers, to form a tree of components. Currently, the root component of
+this tree is a @samp{canvas} component, which allows manual layout of its child
+components.
+
+Components (non-container):
+
+@itemize
+@item label
+@item image
+@item progress_bar
+@item circular_progress
+@item list (currently hard coded to be a boot menu list)
+@end itemize
+
+Containers:
+
+@itemize
+@item canvas
+@item hbox
+@item vbox
+@end itemize
+
+The GUI component instances are created by the theme loader in
+@file{gfxmenu/theme_loader.c} when a theme is loaded. Theme files specify
+statements such as @samp{+vbox@{ +label @{ text="Hello" @} +label@{ text="World" @} @}}
+to add components to the component tree root. By nesting the component
+creation statements in the theme file, the instantiated components are nested
+the same way.
+
+When a component is added to a container, that new child is considered @strong{owned}
+by the container. Great care should be taken if the caller retains a
+reference to the child component, since it will be destroyed if its parent
+container is destroyed. A better choice instead of storing a pointer to the
+child component is to use the component ID to find the desired component.
+Component IDs do not have to be unique (it is often useful to have multiple
+components with an ID of "__timeout__", for instance).
+
+In order to access and use components in the component tree, there are two
+functions (defined in @file{gfxmenu/gui_util.c}) that are particularly useful:
+
+@itemize
+
+@item @code{grub_gui_find_by_id (root, id, callback, userdata)}:
+
+This function ecursively traverses the component tree rooted at @var{root}, and
+for every component that has an ID equal to @var{id}, calls the function pointed
+to by @var{callback} with the matching component and the void pointer @var{userdata}
+as arguments. The callback function can do whatever is desired to use the
+component passed in.
+
+@item @code{grub_gui_iterate_recursively (root, callback, userdata)}:
+
+This function calls the function pointed to by @var{callback} for every
+component that is a descendant of @var{root} in the component tree. When the
+callback function is called, the component and the void pointer @var{userdata}
+as arguments. The callback function can do whatever is desired to use the
+component passed in.
+@end itemize
+
+@node Command Line Window
+@section Command Line Window
+
+The terminal window used to provide command line access within the graphical
+menu is managed by @file{gfxmenu/view.c}. The @samp{gfxterm} terminal is used, and
+it has been modified to allow rendering to an offscreen render target to allow
+it to be composed into the double buffering system that the graphical menu
+view uses. This is bad for performance, however, so it would probably be a
+good idea to make it possible to temporarily disable double buffering as long
+as the terminal window is visible. There are still unresolved problems that
+occur when commands are executed from the terminal window that change the
+graphics mode. It's possible that making @code{grub_video_restore()} return to
+the graphics mode that was in use before @code{grub_video_setup()} was called
+might fix some of the problems.
+
+
+@node Copying This Manual
+@appendix Copying This Manual
+
+@menu
+* GNU Free Documentation License:: License for copying this manual.
+@end menu
+
+@include fdl.texi
+
+
+@node Index
+@unnumbered Index
+
+@c Currently, we use only the Concept Index.
+@printindex cp
+
+@bye
diff --git a/docs/grub.cfg b/docs/grub.cfg
new file mode 100644
index 0000000..e14cdb7
--- /dev/null
+++ b/docs/grub.cfg
@@ -0,0 +1,75 @@
+#
+# Sample GRUB configuration file
+#
+
+# Boot automatically after 30 secs.
+set timeout=30
+
+# By default, boot the first entry.
+set default=0
+
+# Fallback to the second entry.
+set fallback=1
+
+# For booting GNU/Hurd
+menuentry "GNU (aka GNU/Hurd)" {
+ set root=(hd0,1)
+ multiboot /boot/gnumach.gz root=device:hd0s1
+ module /hurd/ext2fs.static ext2fs --readonly \
+ --multiboot-command-line='${kernel-command-line}' \
+ --host-priv-port='${host-port}' \
+ --device-master-port='${device-port}' \
+ --exec-server-task='${exec-task}' -T typed '${root}' \
+ '$(task-create)' '$(task-resume)'
+ module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'
+}
+
+# For booting GNU/Linux
+menuentry "GNU/Linux" {
+ set root=(hd0,1)
+ linux /vmlinuz root=/dev/sda1
+ initrd /initrd.img
+}
+
+# For booting FreeBSD
+menuentry "FreeBSD (or GNU/kFreeBSD), direct boot" {
+ set root=(hd0,1,a)
+ kfreebsd /boot/kernel/kernel
+ kfreebsd_loadenv /boot/device.hints
+ kfreebsd_module /boot/splash.bmp type=splash_image_data
+ set kFreeBSD.vfs.root.mountfrom=ufs:ad0s1a
+}
+menuentry "FreeBSD (or GNU/kFreeBSD), via /boot/loader" {
+ set root=(hd0,1,a)
+ kfreebsd /boot/loader
+}
+
+# For booting NetBSD
+menuentry "NetBSD" {
+ set root=(hd0,1,a)
+ knetbsd /netbsd
+}
+
+# For booting OpenBSD
+menuentry "OpenBSD" {
+ set root=(hd0,1,a)
+ kopenbsd /bsd
+}
+
+# For booting Microsoft Windows
+menuentry "Microsoft Windows" {
+ set root=(hd0,1)
+ chainloader +1
+}
+
+# For booting Memtest86+
+menuentry "Memtest86+" {
+ set root=(hd0,1)
+ linux16 /memtest86+.bin
+}
+
+# Change the colors.
+menuentry "Change the colors" {
+ set menu_color_normal=light-green/brown
+ set menu_color_highlight=red/blue
+}
diff --git a/docs/grub.info b/docs/grub.info
new file mode 100644
index 0000000..fe00c44
--- /dev/null
+++ b/docs/grub.info
@@ -0,0 +1,5228 @@
+This is /home/phcoder/grub2/bzr/grub-1.99/docs/grub.info, produced by
+makeinfo version 4.13 from
+/home/phcoder/grub2/bzr/grub-1.99/docs/grub.texi.
+
+This manual is for GNU GRUB (version 1.99, 14 May 2011).
+
+ Copyright (C) 1999,2000,2001,2002,2004,2006,2008,2009,2010 Free
+Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.2 or any later version published by the Free Software
+ Foundation; with no Invariant Sections.
+
+INFO-DIR-SECTION Kernel
+START-INFO-DIR-ENTRY
+* GRUB: (grub). The GRand Unified Bootloader
+* grub-install: (grub)Invoking grub-install. Install GRUB on your drive
+* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration
+* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2.
+* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image
+END-INFO-DIR-ENTRY
+
+
+File: grub.info, Node: Top, Next: Introduction, Up: (dir)
+
+GNU GRUB manual
+***************
+
+This is the documentation of GNU GRUB, the GRand Unified Bootloader, a
+flexible and powerful boot loader program for a wide range of
+architectures.
+
+ This edition documents version 1.99.
+
+ This manual is for GNU GRUB (version 1.99, 14 May 2011).
+
+ Copyright (C) 1999,2000,2001,2002,2004,2006,2008,2009,2010 Free
+Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.2 or any later version published by the Free Software
+ Foundation; with no Invariant Sections.
+
+* Menu:
+
+* Introduction:: Capturing the spirit of GRUB
+* Naming convention:: Names of your drives in GRUB
+* Installation:: Installing GRUB on your drive
+* Booting:: How to boot different operating systems
+* Configuration:: Writing your own configuration file
+* Theme file format:: Format of GRUB theme files
+* Network:: Downloading OS images from a network
+* Serial terminal:: Using GRUB via a serial line
+* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys
+* Images:: GRUB image files
+* Filesystem:: Filesystem syntax and semantics
+* Interface:: The menu and the command-line
+* Environment:: GRUB environment variables
+* Commands:: The list of available builtin commands
+* Security:: Authentication and authorisation
+* Supported kernels:: The list of supported kernels
+* Troubleshooting:: Error messages produced by GRUB
+* Invoking grub-install:: How to use the GRUB installer
+* Invoking grub-mkconfig:: Generate a GRUB configuration file
+* Invoking grub-mkpasswd-pbkdf2::
+ Generate GRUB password hashes
+* Invoking grub-mkrescue:: Make a GRUB rescue image
+* Obtaining and Building GRUB:: How to obtain and build GRUB
+* Reporting bugs:: Where you should send a bug report
+* Future:: Some future plans on GRUB
+* Copying This Manual:: Copying This Manual
+* Index::
+
+
+File: grub.info, Node: Introduction, Next: Naming convention, Prev: Top, Up: Top
+
+1 Introduction to GRUB
+**********************
+
+* Menu:
+
+* Overview:: What exactly GRUB is and how to use it
+* History:: From maggot to house fly
+* Changes from GRUB Legacy:: Differences from previous versions
+* Features:: GRUB features
+* Role of a boot loader:: The role of a boot loader
+
+
+File: grub.info, Node: Overview, Next: History, Up: Introduction
+
+1.1 Overview
+============
+
+Briefly, a "boot loader" is the first software program that runs when a
+computer starts. It is responsible for loading and transferring
+control to an operating system "kernel" software (such as Linux or GNU
+Mach). The kernel, in turn, initializes the rest of the operating
+system (e.g. a GNU system).
+
+ GNU GRUB is a very powerful boot loader, which can load a wide
+variety of free operating systems, as well as proprietary operating
+systems with chain-loading(1) (*note Overview-Footnote-1::). GRUB is
+designed to address the complexity of booting a personal computer; both
+the program and this manual are tightly bound to that computer platform,
+although porting to other platforms may be addressed in the future.
+
+ One of the important features in GRUB is flexibility; GRUB
+understands filesystems and kernel executable formats, so you can load
+an arbitrary operating system the way you like, without recording the
+physical position of your kernel on the disk. Thus you can load the
+kernel just by specifying its file name and the drive and partition
+where the kernel resides.
+
+ When booting with GRUB, you can use either a command-line interface
+(*note Command-line interface::), or a menu interface (*note Menu
+interface::). Using the command-line interface, you type the drive
+specification and file name of the kernel manually. In the menu
+interface, you just select an OS using the arrow keys. The menu is
+based on a configuration file which you prepare beforehand (*note
+Configuration::). While in the menu, you can switch to the command-line
+mode, and vice-versa. You can even edit menu entries before using them.
+
+ In the following chapters, you will learn how to specify a drive, a
+partition, and a file name (*note Naming convention::) to GRUB, how to
+install GRUB on your drive (*note Installation::), and how to boot your
+OSes (*note Booting::), step by step.
+
+
+File: grub.info, Node: Overview-Footnotes, Up: Overview
+
+ (1) "chain-load" is the mechanism for loading unsupported operating
+systems by loading another boot loader. It is typically used for
+loading DOS or Windows.
+
+
+File: grub.info, Node: History, Next: Changes from GRUB Legacy, Prev: Overview, Up: Introduction
+
+1.2 History of GRUB
+===================
+
+GRUB originated in 1995 when Erich Boleyn was trying to boot the GNU
+Hurd with the University of Utah's Mach 4 microkernel (now known as GNU
+Mach). Erich and Brian Ford designed the Multiboot Specification
+(*note Multiboot Specification: (multiboot)Top.), because they were
+determined not to add to the large number of mutually-incompatible PC
+boot methods.
+
+ Erich then began modifying the FreeBSD boot loader so that it would
+understand Multiboot. He soon realized that it would be a lot easier to
+write his own boot loader from scratch than to keep working on the
+FreeBSD boot loader, and so GRUB was born.
+
+ Erich added many features to GRUB, but other priorities prevented him
+from keeping up with the demands of its quickly-expanding user base. In
+1999, Gordon Matzigkeit and Yoshinori K. Okuji adopted GRUB as an
+official GNU package, and opened its development by making the latest
+sources available via anonymous CVS. *Note Obtaining and Building
+GRUB::, for more information.
+
+ Over the next few years, GRUB was extended to meet many needs, but it
+quickly became clear that its design was not keeping up with the
+extensions being made to it, and we reached the point where it was very
+difficult to make any further changes without breaking existing
+features. Around 2002, Yoshinori K. Okuji started work on PUPA
+(Preliminary Universal Programming Architecture for GNU GRUB), aiming
+to rewrite the core of GRUB to make it cleaner, safer, more robust, and
+more powerful. PUPA was eventually renamed to GRUB 2, and the original
+version of GRUB was renamed to GRUB Legacy. Small amounts of
+maintenance continued to be done on GRUB Legacy, but the last release
+(0.97) was made in 2005 and at the time of writing it seems unlikely
+that there will be another.
+
+ By around 2007, GNU/Linux distributions started to use GRUB 2 to
+limited extents, and by the end of 2009 multiple major distributions
+were installing it by default.
+
+
+File: grub.info, Node: Changes from GRUB Legacy, Next: Features, Prev: History, Up: Introduction
+
+1.3 Differences from previous versions
+======================================
+
+GRUB 2 is a rewrite of GRUB (*note History::), although it shares many
+characteristics with the previous version, now known as GRUB Legacy.
+Users of GRUB Legacy may need some guidance to find their way around
+this new version.
+
+ * The configuration file has a new name (`grub.cfg' rather than
+ `menu.lst' or `grub.conf'), new syntax (*note Configuration::) and
+ many new commands (*note Commands::). Configuration cannot be
+ copied over directly, although most GRUB Legacy users should not
+ find the syntax too surprising.
+
+ * `grub.cfg' is typically automatically generated by `grub-mkconfig'
+ (*note Simple configuration::). This makes it easier to handle
+ versioned kernel upgrades.
+
+ * Partition numbers in GRUB device names now start at 1, not 0
+ (*note Naming convention::).
+
+ * The configuration file is now written in something closer to a full
+ scripting language: variables, conditionals, and loops are
+ available.
+
+ * A small amount of persistent storage is available across reboots,
+ using the `save_env' and `load_env' commands in GRUB and the
+ `grub-editenv' utility. This is not available in all
+ configurations (*note Environment block::).
+
+ * GRUB 2 has more reliable ways to find its own files and those of
+ target kernels on multiple-disk systems, and has commands (*note
+ search::) to find devices using file system labels or Universally
+ Unique Identifiers (UUIDs).
+
+ * GRUB 2 is available for several other types of system in addition
+ to the PC BIOS systems supported by GRUB Legacy: PC EFI, PC
+ coreboot, PowerPC, SPARC, and MIPS Lemote Yeeloong are all
+ supported.
+
+ * Many more file systems are supported, including but not limited to
+ ext4, HFS+, and NTFS.
+
+ * GRUB 2 can read files directly from LVM and RAID devices.
+
+ * A graphical terminal and a graphical menu system are available.
+
+ * GRUB 2's interface can be translated, including menu entry names.
+
+ * The image files (*note Images::) that make up GRUB have been
+ reorganised; Stage 1, Stage 1.5, and Stage 2 are no more.
+
+ * GRUB 2 puts many facilities in dynamically loaded modules,
+ allowing the core image to be smaller, and allowing the core image
+ to be built in more flexible ways.
+
+
+File: grub.info, Node: Features, Next: Role of a boot loader, Prev: Changes from GRUB Legacy, Up: Introduction
+
+1.4 GRUB features
+=================
+
+The primary requirement for GRUB is that it be compliant with the
+"Multiboot Specification", which is described in *note Multiboot
+Specification: (multiboot)Top.
+
+ The other goals, listed in approximate order of importance, are:
+
+ * Basic functions must be straightforward for end-users.
+
+ * Rich functionality to support kernel experts and designers.
+
+ * Backward compatibility for booting FreeBSD, NetBSD, OpenBSD, and
+ Linux. Proprietary kernels (such as DOS, Windows NT, and OS/2) are
+ supported via a chain-loading function.
+
+ Except for specific compatibility modes (chain-loading and the Linux
+"piggyback" format), all kernels will be started in much the same state
+as in the Multiboot Specification. Only kernels loaded at 1 megabyte or
+above are presently supported. Any attempt to load below that boundary
+will simply result in immediate failure and an error message reporting
+the problem.
+
+ In addition to the requirements above, GRUB has the following
+features (note that the Multiboot Specification doesn't require all the
+features that GRUB supports):
+
+Recognize multiple executable formats
+ Support many of the "a.out" variants plus "ELF". Symbol tables are
+ also loaded.
+
+Support non-Multiboot kernels
+ Support many of the various free 32-bit kernels that lack Multiboot
+ compliance (primarily FreeBSD, NetBSD, OpenBSD, and Linux).
+ Chain-loading of other boot loaders is also supported.
+
+Load multiples modules
+ Fully support the Multiboot feature of loading multiple modules.
+
+Load a configuration file
+ Support a human-readable text configuration file with preset boot
+ commands. You can also load another configuration file dynamically
+ and embed a preset configuration file in a GRUB image file. The
+ list of commands (*note Commands::) are a superset of those
+ supported on the command-line. An example configuration file is
+ provided in *note Configuration::.
+
+Provide a menu interface
+ A menu interface listing preset boot commands, with a programmable
+ timeout, is available. There is no fixed limit on the number of
+ boot entries, and the current implementation has space for several
+ hundred.
+
+Have a flexible command-line interface
+ A fairly flexible command-line interface, accessible from the menu,
+ is available to edit any preset commands, or write a new boot
+ command set from scratch. If no configuration file is present,
+ GRUB drops to the command-line.
+
+ The list of commands (*note Commands::) are a subset of those
+ supported for configuration files. Editing commands closely
+ resembles the Bash command-line (*note Bash: (features)Command
+ Line Editing.), with <TAB>-completion of commands, devices,
+ partitions, and files in a directory depending on context.
+
+Support multiple filesystem types
+ Support multiple filesystem types transparently, plus a useful
+ explicit blocklist notation. The currently supported filesystem
+ types are "Amiga Fast FileSystem (AFFS)", "AtheOS fs", "BeFS",
+ "cpio", "Linux ext2/ext3/ext4", "DOS FAT12/FAT16/FAT32", "HFS",
+ "HFS+", "ISO9660", "JFS", "Minix fs", "nilfs2", "NTFS",
+ "ReiserFS", "Amiga Smart FileSystem (SFS)", "tar", "UDF", "BSD
+ UFS/UFS2", and "XFS". *Note Filesystem::, for more information.
+
+Support automatic decompression
+ Can decompress files which were compressed by `gzip' or `xz'(1)
+ (*note Features-Footnote-1::). This function is both automatic and
+ transparent to the user (i.e. all functions operate upon the
+ uncompressed contents of the specified files). This greatly
+ reduces a file size and loading time, a particularly great benefit
+ for floppies.(2) (*note Features-Footnote-2::)
+
+ It is conceivable that some kernel modules should be loaded in a
+ compressed state, so a different module-loading command can be
+ specified to avoid uncompressing the modules.
+
+Access data on any installed device
+ Support reading data from any or all floppies or hard disk(s)
+ recognized by the BIOS, independent of the setting of the root
+ device.
+
+Be independent of drive geometry translations
+ Unlike many other boot loaders, GRUB makes the particular drive
+ translation irrelevant. A drive installed and running with one
+ translation may be converted to another translation without any
+ adverse effects or changes in GRUB's configuration.
+
+Detect all installed RAM
+ GRUB can generally find all the installed RAM on a PC-compatible
+ machine. It uses an advanced BIOS query technique for finding all
+ memory regions. As described on the Multiboot Specification (*note
+ Multiboot Specification: (multiboot)Top.), not all kernels make
+ use of this information, but GRUB provides it for those who do.
+
+Support Logical Block Address mode
+ In traditional disk calls (called "CHS mode"), there is a geometry
+ translation problem, that is, the BIOS cannot access over 1024
+ cylinders, so the accessible space is limited to at least 508 MB
+ and to at most 8GB. GRUB can't universally solve this problem, as
+ there is no standard interface used in all machines. However,
+ several newer machines have the new interface, Logical Block
+ Address ("LBA") mode. GRUB automatically detects if LBA mode is
+ available and uses it if available. In LBA mode, GRUB can access
+ the entire disk.
+
+Support network booting
+ GRUB is basically a disk-based boot loader but also has network
+ support. You can load OS images from a network by using the "TFTP"
+ protocol.
+
+Support remote terminals
+ To support computers with no console, GRUB provides remote terminal
+ support, so that you can control GRUB from a remote host. Only
+ serial terminal support is implemented at the moment.
+
+
+File: grub.info, Node: Features-Footnotes, Up: Features
+
+ (1) Only CRC32 data integrity check is supported (xz default is
+CRC64 so one should use -check=crc32 option). LZMA BCJ filters are
+supported.
+
+ (2) There are a few pathological cases where loading a very badly
+organized ELF kernel might take longer, but in practice this never
+happen.
+
+
+File: grub.info, Node: Role of a boot loader, Prev: Features, Up: Introduction
+
+1.5 The role of a boot loader
+=============================
+
+The following is a quotation from Gordon Matzigkeit, a GRUB fanatic:
+
+ Some people like to acknowledge both the operating system and
+ kernel when they talk about their computers, so they might say
+ they use "GNU/Linux" or "GNU/Hurd". Other people seem to think
+ that the kernel is the most important part of the system, so they
+ like to call their GNU operating systems "Linux systems."
+
+ I, personally, believe that this is a grave injustice, because the
+ _boot loader_ is the most important software of all. I used to
+ refer to the above systems as either "LILO"(1) (*note Role of a
+ boot loader-Footnote-1::) or "GRUB" systems.
+
+ Unfortunately, nobody ever understood what I was talking about;
+ now I just use the word "GNU" as a pseudonym for GRUB.
+
+ So, if you ever hear people talking about their alleged "GNU"
+ systems, remember that they are actually paying homage to the best
+ boot loader around... GRUB!
+
+ We, the GRUB maintainers, do not (usually) encourage Gordon's level
+of fanaticism, but it helps to remember that boot loaders deserve
+recognition. We hope that you enjoy using GNU GRUB as much as we did
+writing it.
+
+
+File: grub.info, Node: Role of a boot loader-Footnotes, Up: Role of a boot loader
+
+ (1) The LInux LOader, a boot loader that everybody uses, but nobody
+likes.
+
+
+File: grub.info, Node: Naming convention, Next: Installation, Prev: Introduction, Up: Top
+
+2 Naming convention
+*******************
+
+The device syntax used in GRUB is a wee bit different from what you may
+have seen before in your operating system(s), and you need to know it so
+that you can specify a drive/partition.
+
+ Look at the following examples and explanations:
+
+ (fd0)
+
+ First of all, GRUB requires that the device name be enclosed with
+`(' and `)'. The `fd' part means that it is a floppy disk. The number
+`0' is the drive number, which is counted from _zero_. This expression
+means that GRUB will use the whole floppy disk.
+
+ (hd0,msdos2)
+
+ Here, `hd' means it is a hard disk drive. The first integer `0'
+indicates the drive number, that is, the first hard disk, the string
+`msdos' indicates the partition scheme, while the second integer, `2',
+indicates the partition number (or the PC slice number in the BSD
+terminology). The partition numbers are counted from _one_, not from
+zero (as was the case in previous versions of GRUB). This expression
+means the second partition of the first hard disk drive. In this case,
+GRUB uses one partition of the disk, instead of the whole disk.
+
+ (hd0,msdos5)
+
+ This specifies the first "extended partition" of the first hard disk
+drive. Note that the partition numbers for extended partitions are
+counted from `5', regardless of the actual number of primary partitions
+on your hard disk.
+
+ (hd1,msdos1,bsd1)
+
+ This means the BSD `a' partition on first PC slice number of the
+second hard disk.
+
+ Of course, to actually access the disks or partitions with GRUB, you
+need to use the device specification in a command, like `set
+root=(fd0)' or `parttool (hd0,msdos3) hidden-'. To help you find out
+which number specifies a partition you want, the GRUB command-line
+(*note Command-line interface::) options have argument completion. This
+means that, for example, you only need to type
+
+ set root=(
+
+ followed by a <TAB>, and GRUB will display the list of drives,
+partitions, or file names. So it should be quite easy to determine the
+name of your target partition, even with minimal knowledge of the
+syntax.
+
+ Note that GRUB does _not_ distinguish IDE from SCSI - it simply
+counts the drive numbers from zero, regardless of their type. Normally,
+any IDE drive number is less than any SCSI drive number, although that
+is not true if you change the boot sequence by swapping IDE and SCSI
+drives in your BIOS.
+
+ Now the question is, how to specify a file? Again, consider an
+example:
+
+ (hd0,msdos1)/vmlinuz
+
+ This specifies the file named `vmlinuz', found on the first
+partition of the first hard disk drive. Note that the argument
+completion works with file names, too.
+
+ That was easy, admit it. Now read the next chapter, to find out how
+to actually install GRUB on your drive.
+
+
+File: grub.info, Node: Installation, Next: Booting, Prev: Naming convention, Up: Top
+
+3 Installation
+**************
+
+In order to install GRUB as your boot loader, you need to first install
+the GRUB system and utilities under your UNIX-like operating system
+(*note Obtaining and Building GRUB::). You can do this either from the
+source tarball, or as a package for your OS.
+
+ After you have done that, you need to install the boot loader on a
+drive (floppy or hard disk) by using the utility `grub-install' (*note
+Invoking grub-install::) on a UNIX-like OS.
+
+ GRUB comes with boot images, which are normally put in the directory
+`/usr/lib/grub/<cpu>-<platform>' (for BIOS-based machines
+`/usr/lib/grub/i386-pc'). Hereafter, the directory where GRUB images are
+initially placed (normally `/usr/lib/grub/<cpu>-<platform>') will be
+called the "image directory", and the directory where the boot loader
+needs to find them (usually `/boot') will be called the "boot
+directory".
+
+* Menu:
+
+* Installing GRUB using grub-install::
+* Making a GRUB bootable CD-ROM::
+* Device map::
+* BIOS installation::
+
+
+File: grub.info, Node: Installing GRUB using grub-install, Next: Making a GRUB bootable CD-ROM, Up: Installation
+
+3.1 Installing GRUB using grub-install
+======================================
+
+For information on where GRUB should be installed on PC BIOS platforms,
+*note BIOS installation::.
+
+ In order to install GRUB under a UNIX-like OS (such as GNU), invoke
+the program `grub-install' (*note Invoking grub-install::) as the
+superuser ("root").
+
+ The usage is basically very simple. You only need to specify one
+argument to the program, namely, where to install the boot loader. The
+argument has to be either a device file (like `/dev/hda'). For
+example, under Linux the following will install GRUB into the MBR of
+the first IDE disk:
+
+ # grub-install /dev/hda
+
+ Likewise, under GNU/Hurd, this has the same effect:
+
+ # grub-install /dev/hd0
+
+ But all the above examples assume that GRUB should put images under
+the `/boot' directory. If you want GRUB to put images under a directory
+other than `/boot', you need to specify the option `--boot-directory'.
+The typical usage is that you create a GRUB boot floppy with a
+filesystem. Here is an example:
+
+ # mke2fs /dev/fd0
+ # mount -t ext2 /dev/fd0 /mnt
+ # mkdir /mnt/boot
+ # grub-install --boot-directory=/mnt/boot /dev/fd0
+ # umount /mnt
+
+ Some BIOSes have a bug of exposing the first partition of a USB
+drive as a floppy instead of exposing the USB drive as a hard disk
+(they call it "USB-FDD" boot). In such cases, you need to install like
+this:
+
+ # losetup /dev/loop0 /dev/sdb1
+ # mount /dev/loop0 /mnt/usb
+ # grub-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0
+
+ This install doesn't conflict with standard install as long as they
+are in separate directories.
+
+ Note that `grub-install' is actually just a shell script and the
+real task is done by `grub-mkimage' and `grub-setup'. Therefore, you
+may run those commands directly to install GRUB, without using
+`grub-install'. Don't do that, however, unless you are very familiar
+with the internals of GRUB. Installing a boot loader on a running OS
+may be extremely dangerous.
+
+
+File: grub.info, Node: Making a GRUB bootable CD-ROM, Next: Device map, Prev: Installing GRUB using grub-install, Up: Installation
+
+3.2 Making a GRUB bootable CD-ROM
+=================================
+
+GRUB supports the "no emulation mode" in the El Torito specification(1)
+(*note Making a GRUB bootable CD-ROM-Footnote-1::). This means that you
+can use the whole CD-ROM from GRUB and you don't have to make a floppy
+or hard disk image file, which can cause compatibility problems.
+
+ For booting from a CD-ROM, GRUB uses a special image called
+`cdboot.img', which is concatenated with `core.img'. The `core.img'
+used for this should be built with at least the `iso9660' and
+`biosdisk' modules. Your bootable CD-ROM will usually also need to
+include a configuration file `grub.cfg' and some other GRUB modules.
+
+ To make a simple generic GRUB rescue CD, you can use the
+`grub-mkrescue' program (*note Invoking grub-mkrescue::):
+
+ $ grub-mkrescue -o grub.iso
+
+ You will often need to include other files in your image. To do
+this, first make a top directory for the bootable image, say, `iso':
+
+ $ mkdir iso
+
+ Make a directory for GRUB:
+
+ $ mkdir -p iso/boot/grub
+
+ If desired, make the config file `grub.cfg' under `iso/boot/grub'
+(*note Configuration::), and copy any files and directories for the
+disc to the directory `iso/'.
+
+ Finally, make the image:
+
+ $ grub-mkrescue -o grub.iso iso
+
+ This produces a file named `grub.iso', which then can be burned into
+a CD (or a DVD), or written to a USB mass storage device.
+
+ The root device will be set up appropriately on entering your
+`grub.cfg' configuration file, so you can refer to file names on the CD
+without needing to use an explicit device name. This makes it easier to
+produce rescue images that will work on both optical drives and USB mass
+storage devices.
+
+
+File: grub.info, Node: Making a GRUB bootable CD-ROM-Footnotes, Up: Making a GRUB bootable CD-ROM
+
+ (1) El Torito is a specification for bootable CD using BIOS
+functions.
+
+
+File: grub.info, Node: Device map, Next: BIOS installation, Prev: Making a GRUB bootable CD-ROM, Up: Installation
+
+3.3 The map between BIOS drives and OS devices
+==============================================
+
+The `grub-mkdevicemap' program can be used to create the "device map
+file". It is often run automatically by tools such as `grub-install'
+if the device map file does not already exist. The file name
+`/boot/grub/device.map' is preferred.
+
+ If the device map file exists, the GRUB utilities (`grub-probe',
+`grub-setup', etc.) read it to map BIOS drives to OS devices. This
+file consists of lines like this:
+
+ DEVICE FILE
+
+ DEVICE is a drive specified in the GRUB syntax (*note Device
+syntax::), and FILE is an OS file, which is normally a device file.
+
+ Historically, the device map file was used because GRUB device names
+had to be used in the configuration file, and they were derived from
+BIOS drive numbers. The map between BIOS drives and OS devices cannot
+always be guessed correctly: for example, GRUB will get the order wrong
+if you exchange the boot sequence between IDE and SCSI in your BIOS.
+
+ Unfortunately, even OS device names are not always stable. Modern
+versions of the Linux kernel may probe drives in a different order from
+boot to boot, and the prefix (`/dev/hd*' versus `/dev/sd*') may change
+depending on the driver subsystem in use. As a result, the device map
+file required frequent editing on some systems.
+
+ GRUB avoids this problem nowadays by using UUIDs or file system
+labels when generating `grub.cfg', and we advise that you do the same
+for any custom menu entries you write. If the device map file does not
+exist, then the GRUB utilities will assume a temporary device map on
+the fly. This is often good enough, particularly in the common case of
+single-disk systems.
+
+ However, the device map file is not entirely obsolete yet, and there
+are still some situations that require it to exist. If necessary, you
+may edit the file if `grub-mkdevicemap' makes a mistake. You can put
+any comments in the file if needed, as the GRUB utilities assume that a
+line is just a comment if the first character is `#'.
+
+
+File: grub.info, Node: BIOS installation, Prev: Device map, Up: Installation
+
+3.4 BIOS installation
+=====================
+
+MBR
+===
+
+The partition table format traditionally used on PC BIOS platforms is
+called the Master Boot Record (MBR) format; this is the format that
+allows up to four primary partitions and additional logical partitions.
+With this partition table format, there are two ways to install GRUB:
+it can be embedded in the area between the MBR and the first partition
+(called by various names, such as the "boot track", "MBR gap", or
+"embedding area", and which is usually at least 31 KiB), or the core
+image can be installed in a file system and a list of the blocks that
+make it up can be stored in the first sector of that partition.
+
+ Each of these has different problems. There is no way to reserve
+space in the embedding area with complete safety, and some proprietary
+software is known to use it to make it difficult for users to work
+around licensing restrictions; and systems are sometimes partitioned
+without leaving enough space before the first partition. On the other
+hand, installing to a filesystem means that GRUB is vulnerable to its
+blocks being moved around by filesystem features such as tail packing,
+or even by aggressive fsck implementations, so this approach is quite
+fragile; and this approach can only be used if the `/boot' filesystem
+is on the same disk that the BIOS boots from, so that GRUB does not
+have to rely on guessing BIOS drive numbers.
+
+ The GRUB development team generally recommends embedding GRUB before
+the first partition, unless you have special requirements. You must
+ensure that the first partition starts at least 31 KiB (63 sectors)
+from the start of the disk; on modern disks, it is often a performance
+advantage to align partitions on larger boundaries anyway, so the first
+partition might start 1 MiB from the start of the disk.
+
+GPT
+===
+
+Some newer systems use the GUID Partition Table (GPT) format. This was
+specified as part of the Extensible Firmware Interface (EFI), but it can
+also be used on BIOS platforms if system software supports it; for
+example, GRUB and GNU/Linux can be used in this configuration. With
+this format, it is possible to reserve a whole partition for GRUB,
+called the BIOS Boot Partition. GRUB can then be embedded into that
+partition without the risk of being overwritten by other software and
+without being contained in a filesystem which might move its blocks
+around.
+
+ When creating a BIOS Boot Partition on a GPT system, you should make
+sure that it is at least 31 KiB in size. (GPT-formatted disks are not
+usually particularly small, so we recommend that you make it larger
+than the bare minimum, such as 1 MiB, to allow plenty of room for
+growth.) You must also make sure that it has the proper partition
+type. Using GNU Parted, you can set this using a command such as the
+following:
+
+ # parted /dev/DISK set PARTITION-NUMBER bios_grub on
+
+ If you are using gdisk, set the partition type to `0xEF02'. With
+partitioning programs that require setting the GUID directly, it should
+be `21686148-6449-6e6f-744e656564454649'.
+
+ *Caution:* Be very careful which partition you select! When GRUB
+finds a BIOS Boot Partition during installation, it will automatically
+overwrite part of it. Make sure that the partition does not contain any
+other data.
+
+
+File: grub.info, Node: Booting, Next: Configuration, Prev: Installation, Up: Top
+
+4 Booting
+*********
+
+GRUB can load Multiboot-compliant kernels in a consistent way, but for
+some free operating systems you need to use some OS-specific magic.
+
+* Menu:
+
+* General boot methods:: How to boot OSes with GRUB generally
+* OS-specific notes:: Notes on some operating systems
+
+
+File: grub.info, Node: General boot methods, Next: OS-specific notes, Up: Booting
+
+4.1 How to boot operating systems
+=================================
+
+GRUB has two distinct boot methods. One of the two is to load an
+operating system directly, and the other is to chain-load another boot
+loader which then will load an operating system actually. Generally
+speaking, the former is more desirable, because you don't need to
+install or maintain other boot loaders and GRUB is flexible enough to
+load an operating system from an arbitrary disk/partition. However, the
+latter is sometimes required, since GRUB doesn't support all the
+existing operating systems natively.
+
+* Menu:
+
+* Loading an operating system directly::
+* Chain-loading::
+
+
+File: grub.info, Node: Loading an operating system directly, Next: Chain-loading, Up: General boot methods
+
+4.1.1 How to boot an OS directly with GRUB
+------------------------------------------
+
+Multiboot (*note Multiboot Specification: (multiboot)Top.) is the
+native format supported by GRUB. For the sake of convenience, there is
+also support for Linux, FreeBSD, NetBSD and OpenBSD. If you want to
+boot other operating systems, you will have to chain-load them (*note
+Chain-loading::).
+
+ FIXME: this section is incomplete.
+
+ 1. Run the command `boot' (*note boot::).
+
+ However, DOS and Windows have some deficiencies, so you might have to
+use more complicated instructions. *Note DOS/Windows::, for more
+information.
+
+
+File: grub.info, Node: Chain-loading, Prev: Loading an operating system directly, Up: General boot methods
+
+4.1.2 Chain-loading an OS
+-------------------------
+
+Operating systems that do not support Multiboot and do not have specific
+support in GRUB (specific support is available for Linux, FreeBSD,
+NetBSD and OpenBSD) must be chain-loaded, which involves loading
+another boot loader and jumping to it in real mode.
+
+ The `chainloader' command (*note chainloader::) is used to set this
+up. It is normally also necessary to load some GRUB modules and set the
+appropriate root device. Putting this together, we get something like
+this, for a Windows system on the first partition of the first hard
+disk:
+
+menuentry "Windows" {
+ insmod chain
+ insmod ntfs
+ set root=(hd0,1)
+ chainloader +1
+}
+
+ On systems with multiple hard disks, an additional workaround may be
+required. *Note DOS/Windows::.
+
+ Chain-loading is only supported on PC BIOS and EFI platforms.
+
+
+File: grub.info, Node: OS-specific notes, Prev: General boot methods, Up: Booting
+
+4.2 Some caveats on OS-specific issues
+======================================
+
+Here, we describe some caveats on several operating systems.
+
+* Menu:
+
+* GNU/Hurd::
+* GNU/Linux::
+* DOS/Windows::
+
+
+File: grub.info, Node: GNU/Hurd, Next: GNU/Linux, Up: OS-specific notes
+
+4.2.1 GNU/Hurd
+--------------
+
+Since GNU/Hurd is Multiboot-compliant, it is easy to boot it; there is
+nothing special about it. But do not forget that you have to specify a
+root partition to the kernel.
+
+ 1. Set GRUB's root device to the same drive as GNU/Hurd's. The
+ command `search --file --set /boot/gnumach.gz' or similar may help
+ you (*note search::).
+
+ 2. Load the kernel and the modules, like this:
+
+ grub> multiboot /boot/gnumach.gz root=device:hd0s1
+ grub> module /hurd/ext2fs.static ext2fs --readonly \
+ --multiboot-command-line='${kernel-command-line}' \
+ --host-priv-port='${host-port}' \
+ --device-master-port='${device-port}' \
+ --exec-server-task='${exec-task}' -T typed '${root}' \
+ '$(task-create)' '$(task-resume)'
+ grub> module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'
+
+ 3. Finally, run the command `boot' (*note boot::).
+
+
+File: grub.info, Node: GNU/Linux, Next: DOS/Windows, Prev: GNU/Hurd, Up: OS-specific notes
+
+4.2.2 GNU/Linux
+---------------
+
+It is relatively easy to boot GNU/Linux from GRUB, because it somewhat
+resembles to boot a Multiboot-compliant OS.
+
+ 1. Set GRUB's root device to the same drive as GNU/Linux's. The
+ command `search --file --set /vmlinuz' or similar may help you
+ (*note search::).
+
+ 2. Load the kernel using the command `linux' (*note linux::):
+
+ grub> linux /vmlinuz root=/dev/sda1
+
+ If you need to specify some kernel parameters, just append them to
+ the command. For example, to set `acpi' to `off', do this:
+
+ grub> linux /vmlinuz root=/dev/sda1 acpi=off
+
+ See the documentation in the Linux source tree for complete
+ information on the available options.
+
+ With `linux' GRUB uses 32-bit protocol. Some BIOS services like APM
+ or EDD aren't available with this protocol. In this case you need
+ to use `linux16'
+
+ grub> linux16 /vmlinuz root=/dev/sda1 acpi=off
+
+ 3. If you use an initrd, execute the command `initrd' (*note initrd::)
+ after `linux':
+
+ grub> initrd /initrd
+
+ If you used `linux16' you need to use `initrd16':
+
+ grub> initrd16 /initrd
+
+ 4. Finally, run the command `boot' (*note boot::).
+
+ *Caution:* If you use an initrd and specify the `mem=' option to the
+kernel to let it use less than actual memory size, you will also have
+to specify the same memory size to GRUB. To let GRUB know the size, run
+the command `uppermem' _before_ loading the kernel. *Note uppermem::,
+for more information.
+
+
+File: grub.info, Node: DOS/Windows, Prev: GNU/Linux, Up: OS-specific notes
+
+4.2.3 DOS/Windows
+-----------------
+
+GRUB cannot boot DOS or Windows directly, so you must chain-load them
+(*note Chain-loading::). However, their boot loaders have some critical
+deficiencies, so it may not work to just chain-load them. To overcome
+the problems, GRUB provides you with two helper functions.
+
+ If you have installed DOS (or Windows) on a non-first hard disk, you
+have to use the disk swapping technique, because that OS cannot boot
+from any disks but the first one. The workaround used in GRUB is the
+command `drivemap' (*note drivemap::), like this:
+
+ drivemap -s (hd0) (hd1)
+
+ This performs a "virtual" swap between your first and second hard
+drive.
+
+ *Caution:* This is effective only if DOS (or Windows) uses BIOS to
+access the swapped disks. If that OS uses a special driver for the
+disks, this probably won't work.
+
+ Another problem arises if you installed more than one set of
+DOS/Windows onto one disk, because they could be confused if there are
+more than one primary partitions for DOS/Windows. Certainly you should
+avoid doing this, but there is a solution if you do want to do so. Use
+the partition hiding/unhiding technique.
+
+ If GRUB "hides" a DOS (or Windows) partition (*note parttool::), DOS
+(or Windows) will ignore the partition. If GRUB "unhides" a DOS (or
+Windows) partition, DOS (or Windows) will detect the partition. Thus,
+if you have installed DOS (or Windows) on the first and the second
+partition of the first hard disk, and you want to boot the copy on the
+first partition, do the following:
+
+ parttool (hd0,1) hidden-
+ parttool (hd0,2) hidden+
+ set root=(hd0,1)
+ chainloader +1
+ parttool ${root} boot+
+ boot
+
+
+File: grub.info, Node: Configuration, Next: Theme file format, Prev: Booting, Up: Top
+
+5 Writing your own configuration file
+*************************************
+
+GRUB is configured using `grub.cfg', usually located under
+`/boot/grub'. This file is quite flexible, but most users will not
+need to write the whole thing by hand.
+
+* Menu:
+
+* Simple configuration:: Recommended for most users
+* Shell-like scripting:: For power users and developers
+* Embedded configuration:: Embedding a configuration file into GRUB
+
+
+File: grub.info, Node: Simple configuration, Next: Shell-like scripting, Up: Configuration
+
+5.1 Simple configuration handling
+=================================
+
+The program `grub-mkconfig' (*note Invoking grub-mkconfig::) generates
+`grub.cfg' files suitable for most cases. It is suitable for use when
+upgrading a distribution, and will discover available kernels and
+attempt to generate menu entries for them.
+
+ `grub-mkconfig' does have some limitations. While adding extra
+custom menu entries to the end of the list can be done by editing
+`/etc/grub.d/40_custom' or creating `/boot/grub/custom.cfg', changing
+the order of menu entries or changing their titles may require making
+complex changes to shell scripts stored in `/etc/grub.d/'. This may be
+improved in the future. In the meantime, those who feel that it would
+be easier to write `grub.cfg' directly are encouraged to do so (*note
+Booting::, and *note Shell-like scripting::), and to disable any system
+provided by their distribution to automatically run `grub-mkconfig'.
+
+ The file `/etc/default/grub' controls the operation of
+`grub-mkconfig'. It is sourced by a shell script, and so must be valid
+POSIX shell input; normally, it will just be a sequence of `KEY=value'
+lines, but if the value contains spaces or other special characters
+then it must be quoted. For example:
+
+ GRUB_TERMINAL_INPUT="console serial"
+
+ Valid keys in `/etc/default/grub' are as follows:
+
+`GRUB_DEFAULT'
+ The default menu entry. This may be a number, in which case it
+ identifies the Nth entry in the generated menu counted from zero,
+ or the title of a menu entry, or the special string `saved'.
+ Using the title may be useful if you want to set a menu entry as
+ the default even though there may be a variable number of entries
+ before it.
+
+ For example, if you have:
+
+ menuentry 'Example GNU/Linux distribution' --class gnu-linux {
+ ...
+ }
+
+ then you can make this the default using:
+
+ GRUB_DEFAULT='Example GNU/Linux distribution'
+
+ If you set this to `saved', then the default menu entry will be
+ that saved by `GRUB_SAVEDEFAULT', `grub-set-default', or
+ `grub-reboot'.
+
+ The default is `0'.
+
+`GRUB_SAVEDEFAULT'
+ If this option is set to `true', then, when an entry is selected,
+ save it as a new default entry for use by future runs of GRUB.
+ This is only useful if `GRUB_DEFAULT=saved'; it is a separate
+ option because `GRUB_DEFAULT=saved' is useful without this option,
+ in conjunction with `grub-set-default' or `grub-reboot'. Unset by
+ default. This option relies on the environment block, which may
+ not be available in all situations (*note Environment block::).
+
+`GRUB_TIMEOUT'
+ Boot the default entry this many seconds after the menu is
+ displayed, unless a key is pressed. The default is `5'. Set to
+ `0' to boot immediately without displaying the menu, or to `-1' to
+ wait indefinitely.
+
+`GRUB_HIDDEN_TIMEOUT'
+ Wait this many seconds for a key to be pressed before displaying
+ the menu. If no key is pressed during that time, boot
+ immediately. Unset by default.
+
+`GRUB_HIDDEN_TIMEOUT_QUIET'
+ In conjunction with `GRUB_HIDDEN_TIMEOUT', set this to `true' to
+ suppress the verbose countdown while waiting for a key to be
+ pressed before displaying the menu. Unset by default.
+
+`GRUB_DEFAULT_BUTTON'
+`GRUB_TIMEOUT_BUTTON'
+`GRUB_HIDDEN_TIMEOUT_BUTTON'
+`GRUB_BUTTON_CMOS_ADDRESS'
+ Variants of the corresponding variables without the `_BUTTON'
+ suffix, used to support vendor-specific power buttons. *Note
+ Vendor power-on keys::.
+
+`GRUB_DISTRIBUTOR'
+ Set by distributors of GRUB to their identifying name. This is
+ used to generate more informative menu entry titles.
+
+`GRUB_TERMINAL_INPUT'
+ Select the terminal input device. You may select multiple devices
+ here, separated by spaces.
+
+ Valid terminal input names depend on the platform, but may include
+ `console' (PC BIOS and EFI consoles), `serial' (serial terminal),
+ `ofconsole' (Open Firmware console), `at_keyboard' (PC AT
+ keyboard, mainly useful with Coreboot), or `usb_keyboard' (USB
+ keyboard using the HID Boot Protocol, for cases where the firmware
+ does not handle this).
+
+ The default is to use the platform's native terminal input.
+
+`GRUB_TERMINAL_OUTPUT'
+ Select the terminal output device. You may select multiple
+ devices here, separated by spaces.
+
+ Valid terminal output names depend on the platform, but may include
+ `console' (PC BIOS and EFI consoles), `serial' (serial terminal),
+ `gfxterm' (graphics-mode output), `ofconsole' (Open Firmware
+ console), or `vga_text' (VGA text output, mainly useful with
+ Coreboot).
+
+ The default is to use the platform's native terminal output.
+
+`GRUB_TERMINAL'
+ If this option is set, it overrides both `GRUB_TERMINAL_INPUT' and
+ `GRUB_TERMINAL_OUTPUT' to the same value.
+
+`GRUB_SERIAL_COMMAND'
+ A command to configure the serial port when using the serial
+ console. *Note serial::. Defaults to `serial'.
+
+`GRUB_CMDLINE_LINUX'
+ Command-line arguments to add to menu entries for the Linux kernel.
+
+`GRUB_CMDLINE_LINUX_DEFAULT'
+ Unless `GRUB_DISABLE_RECOVERY' is set to `true', two menu entries
+ will be generated for each Linux kernel: one default entry and one
+ entry for recovery mode. This option lists command-line arguments
+ to add only to the default menu entry, after those listed in
+ `GRUB_CMDLINE_LINUX'.
+
+`GRUB_CMDLINE_NETBSD'
+`GRUB_CMDLINE_NETBSD_DEFAULT'
+ As `GRUB_CMDLINE_LINUX' and `GRUB_CMDLINE_LINUX_DEFAULT', but for
+ NetBSD.
+
+`GRUB_CMDLINE_XEN'
+`GRUB_CMDLINE_XEN_DEFAULT'
+ As `GRUB_CMDLINE_LINUX' and `GRUB_CMDLINE_LINUX_DEFAULT', but for
+ Linux and Xen.
+
+`GRUB_DISABLE_LINUX_UUID'
+ Normally, `grub-mkconfig' will generate menu entries that use
+ universally-unique identifiers (UUIDs) to identify the root
+ filesystem to the Linux kernel, using a `root=UUID=...' kernel
+ parameter. This is usually more reliable, but in some cases it
+ may not be appropriate. To disable the use of UUIDs, set this
+ option to `true'.
+
+`GRUB_DISABLE_RECOVERY'
+ If this option is set to `true', disable the generation of recovery
+ mode menu entries.
+
+`GRUB_VIDEO_BACKEND'
+ If graphical video support is required, either because the
+ `gfxterm' graphical terminal is in use or because
+ `GRUB_GFXPAYLOAD_LINUX' is set, then `grub-mkconfig' will normally
+ load all available GRUB video drivers and use the one most
+ appropriate for your hardware. If you need to override this for
+ some reason, then you can set this option.
+
+ After `grub-install' has been run, the available video drivers are
+ listed in `/boot/grub/video.lst'.
+
+`GRUB_GFXMODE'
+ Set the resolution used on the `gfxterm' graphical terminal. Note
+ that you can only use modes which your graphics card supports via
+ VESA BIOS Extensions (VBE), so for example native LCD panel
+ resolutions may not be available. The default is `640x480'.
+ *Note gfxmode::.
+
+`GRUB_BACKGROUND'
+ Set a background image for use with the `gfxterm' graphical
+ terminal. The value of this option must be a file readable by
+ GRUB at boot time, and it must end with `.png', `.tga', `.jpg', or
+ `.jpeg'. The image will be scaled if necessary to fit the screen.
+
+`GRUB_THEME'
+ Set a theme for use with the `gfxterm' graphical terminal.
+
+`GRUB_GFXPAYLOAD_LINUX'
+ Set to `text' to force the Linux kernel to boot in normal text
+ mode, `keep' to preserve the graphics mode set using
+ `GRUB_GFXMODE', `WIDTHxHEIGHT'[`xDEPTH'] to set a particular
+ graphics mode, or a sequence of these separated by commas or
+ semicolons to try several modes in sequence. *Note gfxpayload::.
+
+ Depending on your kernel, your distribution, your graphics card,
+ and the phase of the moon, note that using this option may cause
+ GNU/Linux to suffer from various display problems, particularly
+ during the early part of the boot sequence. If you have problems,
+ set this option to `text' and GRUB will tell Linux to boot in
+ normal text mode.
+
+`GRUB_DISABLE_OS_PROBER'
+ Normally, `grub-mkconfig' will try to use the external `os-prober'
+ program, if installed, to discover other operating systems
+ installed on the same system and generate appropriate menu entries
+ for them. Set this option to `true' to disable this.
+
+`GRUB_INIT_TUNE'
+ Play a tune on the speaker when GRUB starts. This is particularly
+ useful for users unable to see the screen. The value of this
+ option is passed directly to *note play::.
+
+`GRUB_BADRAM'
+ If this option is set, GRUB will issue a *note badram:: command to
+ filter out specified regions of RAM.
+
+`GRUB_PRELOAD_MODULES'
+ This option may be set to a list of GRUB module names separated by
+ spaces. Each module will be loaded as early as possible, at the
+ start of `grub.cfg'.
+
+
+ For more detailed customisation of `grub-mkconfig''s output, you may
+edit the scripts in `/etc/grub.d' directly. `/etc/grub.d/40_custom' is
+particularly useful for adding entire custom menu entries; simply type
+the menu entries you want to add at the end of that file, making sure
+to leave at least the first two lines intact.
+
+
+File: grub.info, Node: Shell-like scripting, Next: Embedded configuration, Prev: Simple configuration, Up: Configuration
+
+5.2 Writing full configuration files directly
+=============================================
+
+`grub.cfg' is written in GRUB's built-in scripting language, which has
+a syntax quite similar to that of GNU Bash and other Bourne shell
+derivatives.
+
+Words
+=====
+
+A "word" is a sequence of characters considered as a single unit by
+GRUB. Words are separated by "metacharacters", which are the following
+plus space, tab, and newline:
+
+ { } | & $ ; < >
+
+ Quoting may be used to include metacharacters in words; see below.
+
+Reserved words
+==============
+
+Reserved words have a special meaning to GRUB. The following words are
+recognised as reserved when unquoted and either the first word of a
+simple command or the third word of a `for' command:
+
+ ! [[ ]] { }
+ case do done elif else esac fi for function
+ if in menuentry select then time until while
+
+ Not all of these reserved words have a useful purpose yet; some are
+reserved for future expansion.
+
+Quoting
+=======
+
+Quoting is used to remove the special meaning of certain characters or
+words. It can be used to treat metacharacters as part of a word, to
+prevent reserved words from being recognised as such, and to prevent
+variable expansion.
+
+ There are three quoting mechanisms: the escape character, single
+quotes, and double quotes.
+
+ A non-quoted backslash (\) is the "escape character". It preserves
+the literal value of the next character that follows, with the
+exception of newline.
+
+ Enclosing characters in single quotes preserves the literal value of
+each character within the quotes. A single quote may not occur between
+single quotes, even when preceded by a backslash.
+
+ Enclosing characters in double quotes preserves the literal value of
+all characters within the quotes, with the exception of `$' and `\'.
+The `$' character retains its special meaning within double quotes.
+The backslash retains its special meaning only when followed by one of
+the following characters: `$', `"', `\', or newline. A
+backslash-newline pair is treated as a line continuation (that is, it is
+removed from the input stream and effectively ignored(1) (*note
+Shell-like scripting-Footnote-1::)). A double quote may be quoted
+within double quotes by preceding it with a backslash.
+
+Variable expansion
+==================
+
+The `$' character introduces variable expansion. The variable name to
+be expanded may be enclosed in braces, which are optional but serve to
+protect the variable to be expanded from characters immediately
+following it which could be interpreted as part of the name.
+
+ Normal variable names begin with an alphabetic character, followed
+by zero or more alphanumeric characters. These names refer to entries
+in the GRUB environment (*note Environment::).
+
+ Positional variable names consist of one or more digits. They
+represent parameters passed to function calls, with `$1' representing
+the first parameter, and so on.
+
+ The special variable name `?' expands to the exit status of the most
+recently executed command. When positional variable names are active,
+other special variable names `@', `*' and `#' are defined and they
+expand to all positional parameters with necessary quoting, positional
+parameters without any quoting, and positional parameter count
+respectively.
+
+Comments
+========
+
+A word beginning with `#' causes that word and all remaining characters
+on that line to be ignored.
+
+Simple commands
+===============
+
+A "simple command" is a sequence of words separated by spaces or tabs
+and terminated by a semicolon or a newline. The first word specifies
+the command to be executed. The remaining words are passed as
+arguments to the invoked command.
+
+ The return value of a simple command is its exit status. If the
+reserved word `!' precedes the command, then the return value is
+instead the logical negation of the command's exit status.
+
+Compound commands
+=================
+
+A "compound command" is one of the following:
+
+for NAME in WORD ...; do LIST; done
+ The list of words following `in' is expanded, generating a list of
+ items. The variable NAME is set to each element of this list in
+ turn, and LIST is executed each time. The return value is the
+ exit status of the last command that executes. If the expansion
+ of the items following `in' results in an empty list, no commands
+ are executed, and the return status is 0.
+
+if LIST; then LIST; [elif LIST; then LIST;] ... [else LIST;] fi
+ The `if' LIST is executed. If its exit status is zero, the `then'
+ LIST is executed. Otherwise, each `elif' LIST is executed in
+ turn, and if its exit status is zero, the corresponding `then'
+ LIST is executed and the command completes. Otherwise, the `else'
+ LIST is executed, if present. The exit status is the exit status
+ of the last command executed, or zero if no condition tested true.
+
+while COND; do LIST; done
+until COND; do LIST; done
+ The `while' command continuously executes the `do' LIST as long as
+ the last command in COND returns an exit status of zero. The
+ `until' command is identical to the `while' command, except that
+ the test is negated; the `do' LIST is executed as long as the last
+ command in COND returns a non-zero exit status. The exit status
+ of the `while' and `until' commands is the exit status of the last
+ `do' LIST command executed, or zero if none was executed.
+
+function NAME { COMMAND; ... }
+ This defines a function named NAME. The "body" of the function is
+ the list of commands within braces, each of which must be
+ terminated with a semicolon or a newline. This list of commands
+ will be executed whenever NAME is specified as the name of a
+ simple command. Function definitions do not affect the exit
+ status in `$?'. When executed, the exit status of a function is
+ the exit status of the last command executed in the body.
+
+menuentry TITLE [`--class=class' ...] [`--users=users'] [`--hotkey=key'] { COMMAND; ... }
+ *Note menuentry::.
+
+Built-in Commands
+=================
+
+Some built-in commands are also provided by GRUB script to help script
+writers perform actions that are otherwise not possible. For example,
+these include commands to jump out of a loop without fully completing
+it, etc.
+
+break [`n']
+ Exit from within a `for', `while', or `until' loop. If `n' is
+ specified, break `n' levels. `n' must be greater than or equal to
+ 1. If `n' is greater than the number of enclosing loops, all
+ enclosing loops are exited. The return value is 0 unless `n' is
+ not greater than or equal to 1.
+
+continue [`n']
+ Resume the next iteration of the enclosing `for', `while' or
+ `until' loop. If `n' is specified, resume at the `n'th enclosing
+ loop. `n' must be greater than or equal to 1. If `n' is greater
+ than the number of enclosing loops, the last enclosing loop (the
+ "top-level" loop) is resumed. The return value is 0 unless `n' is
+ not greater than or equal to 1.
+
+return [`n']
+ Causes a function to exit with the return value specified by `n'.
+ If `n' is omitted, the return status is that of the last command
+ executed in the function body. If used outside a function the
+ return status is false.
+
+shift [`n']
+ The positional parameters from `n'+1 ... are renamed to `$1'....
+ Parameters represented by the numbers `$#' down to `$#'-`n'+1 are
+ unset. `n' must be a non-negative number less than or equal to
+ `$#'. If `n' is 0, no parameters are changed. If `n' is not
+ given, it is assumed to be 1. If `n' is greater than `$#', the
+ positional parameters are not changed. The return status is
+ greater than zero if `n' is greater than `$#' or less than zero;
+ otherwise 0.
+
+
+
+File: grub.info, Node: Shell-like scripting-Footnotes, Up: Shell-like scripting
+
+ (1) Currently a backslash-newline pair within a variable name is not
+handled properly, so use this feature with some care.
+
+
+File: grub.info, Node: Embedded configuration, Prev: Shell-like scripting, Up: Configuration
+
+5.3 Embedding a configuration file into GRUB
+============================================
+
+GRUB supports embedding a configuration file directly into the core
+image, so that it is loaded before entering normal mode. This is
+useful, for example, when it is not straightforward to find the real
+configuration file, or when you need to debug problems with loading
+that file. `grub-install' uses this feature when it is not using BIOS
+disk functions or when installing to a different disk from the one
+containing `/boot/grub', in which case it needs to use the `search'
+command (*note search::) to find `/boot/grub'.
+
+ To embed a configuration file, use the `-c' option to
+`grub-mkimage'. The file is copied into the core image, so it may
+reside anywhere on the file system, and may be removed after running
+`grub-mkimage'.
+
+ After the embedded configuration file (if any) is executed, GRUB
+will load the `normal' module (*note normal::), which will then read
+the real configuration file from `$prefix/grub.cfg'. By this point, the
+`root' variable will also have been set to the root device name. For
+example, `prefix' might be set to `(hd0,1)/boot/grub', and `root' might
+be set to `hd0,1'. Thus, in most cases, the embedded configuration
+file only needs to set the `prefix' and `root' variables, and then drop
+through to GRUB's normal processing. A typical example of this might
+look like this:
+
+ search.fs_uuid 01234567-89ab-cdef-0123-456789abcdef root
+ set prefix=($root)/boot/grub
+
+ (The `search_fs_uuid' module must be included in the core image for
+this example to work.)
+
+ In more complex cases, it may be useful to read other configuration
+files directly from the embedded configuration file. This allows such
+things as reading files not called `grub.cfg', or reading files from a
+directory other than that where GRUB's loadable modules are installed.
+To do this, include the `configfile' and `normal' modules in the core
+image, and embed a configuration file that uses the `configfile'
+command to load another file. The following example of this also
+requires the `echo', `search_label', and `test' modules to be included
+in the core image:
+
+ search.fs_label grub root
+ if [ -e /boot/grub/example/test1.cfg ]; then
+ set prefix=($root)/boot/grub
+ configfile /boot/grub/example/test1.cfg
+ else
+ if [ -e /boot/grub/example/test2.cfg ]; then
+ set prefix=($root)/boot/grub
+ configfile /boot/grub/example/test2.cfg
+ else
+ echo "Could not find an example configuration file!"
+ fi
+ fi
+
+ The embedded configuration file may not contain menu entries
+directly, but may only read them from elsewhere using `configfile'.
+
+
+File: grub.info, Node: Theme file format, Next: Network, Prev: Configuration, Up: Top
+
+6 Theme file format
+*******************
+
+6.1 Introduction
+================
+
+The GRUB graphical menu supports themes that can customize the layout
+and appearance of the GRUB boot menu. The theme is configured through
+a plain text file that specifies the layout of the various GUI
+components (including the boot menu, timeout progress bar, and text
+messages) as well as the appearance using colors, fonts, and images.
+Example is available in docs/example_theme.txt
+
+6.2 Theme Elements
+==================
+
+6.2.1 Colors
+------------
+
+Colors can be specified in several ways:
+
+ * HTML-style "#RRGGBB" or "#RGB" format, where *R*, *G*, and *B* are
+ hexadecimal digits (e.g., "#8899FF")
+
+ * as comma-separated decimal RGB values (e.g., "128, 128, 255")
+
+ * with "SVG 1.0 color names" (e.g., "cornflowerblue") which must be
+ specified in lowercase.
+
+6.2.2 Fonts
+-----------
+
+The fonts GRUB uses "PFF2 font format" bitmap fonts. Fonts are
+specified with full font names. Currently there is no provision for a
+preference list of fonts, or deriving one font from another. Fonts are
+loaded with the "loadfont" command in GRUB. To see the list of loaded
+fonts, execute the "lsfonts" command. If there are too many fonts to
+fit on screen, do "set pager=1" before executing "lsfonts".
+
+6.2.3 Progress Bar
+------------------
+
+Figure 6.1
+
+Figure 6.2
+
+ Progress bars are used to display the remaining time before GRUB
+boots the default menu entry. To create a progress bar that will
+display the remaining time before automatic boot, simply create a
+"progress_bar" component with the id "__timeout__". This indicates to
+GRUB that the progress bar should be updated as time passes, and it
+should be made invisible if the countdown to automatic boot is
+interrupted by the user.
+
+ Progress bars may optionally have text displayed on them. This is
+controlled through the "show_text" property, which can be set to either
+"true" or "false" to control whether text is displayed. When GRUB is
+counting down to automatic boot, the text informs the user of the
+number of seconds remaining.
+
+6.2.4 Circular Progress Indicator
+---------------------------------
+
+The circular progress indicator functions similarly to the progress
+bar. When given an id of "__timeout__", GRUB updates the circular
+progress indicator's value to indicate the time remaining. For the
+circular progress indicator, there are two images used to render it:
+the *center* image, and the *tick* image. The center image is rendered
+in the center of the component, while the tick image is used to render
+each mark along the circumference of the indicator.
+
+6.2.5 Labels
+------------
+
+Text labels can be placed on the boot screen. The font, color, and
+horizontal alignment can be specified for labels. If a label is given
+the id "__timeout__", then the "text" property for that label is also
+updated with a message informing the user of the number of seconds
+remaining until automatic boot. This is useful in case you want the
+text displayed somewhere else instead of directly on the progress bar.
+
+6.2.6 Boot Menu
+---------------
+
+The boot menu where GRUB displays the menu entries from the "grub.cfg"
+file. It is a list of items, where each item has a title and an
+optional icon. The icon is selected based on the *classes* specified
+for the menu entry. If there is a PNG file named "myclass.png" in the
+"grub/themes/icons" directory, it will be displayed for items which
+have the class *myclass*. The boot menu can be customized in several
+ways, such as the font and color used for the menu entry title, and by
+specifying styled boxes for the menu itself and for the selected item
+highlight.
+
+6.2.7 Styled Boxes
+------------------
+
+One of the most important features for customizing the layout is the
+use of *styled boxes*. A styled box is composed of 9 rectangular (and
+potentially empty) regions, which are used to seamlessly draw the
+styled box on screen:
+
+Northwest (nw) North (n) Northeast (ne)
+West (w) Center (c) East (e)
+Southwest (sw) South (s) Southeast (se)
+
+ To support any size of box on screen, the center slice and the
+slices for the top, bottom, and sides are all scaled to the correct
+size for the component on screen, using the following rules:
+
+ 1. The edge slices (north, south, east, and west) are scaled in the
+ direction of the edge they are adjacent to. For instance, the
+ west slice is scaled vertically.
+
+ 2. The corner slices (northwest, northeast, southeast, and southwest)
+ are not scaled.
+
+ 3. The center slice is scaled to fill the remaining space in the
+ middle.
+
+ As an example of how an image might be sliced up, consider the
+styled box used for a terminal view.
+
+Figure 6.3
+
+6.2.8 Creating Styled Box Images
+--------------------------------
+
+The Inkscape_ scalable vector graphics editor is a very useful tool for
+creating styled box images. One process that works well for slicing a
+drawing into the necessary image slices is:
+
+ 1. Create or open the drawing you'd like use.
+
+ 2. Create a new layer on the top of the layer stack. Make it
+ visible. Select this layer as the current layer.
+
+ 3. Draw 9 rectangles on your drawing where you'd like the slices to
+ be. Clear the fill option, and set the stroke to 1 pixel wide
+ solid stroke. The corners of the slices must meet precisely; if
+ it is off by a single pixel, it will probably be evident when the
+ styled box is rendered in the GRUB menu. You should probably go
+ to File | Document Properties | Grids and enable a grid or create
+ a guide (click on one of the rulers next to the drawing and drag
+ over the drawing; release the mouse button to place the guide) to
+ help place the rectangles precisely.
+
+ 4. Right click on the center slice rectangle and choose Object
+ Properties. Change the "Id" to "slice_c" and click Set. Repeat
+ this for the remaining 8 rectangles, giving them Id values of
+ "slice_n", "slice_ne", "slice_e", and so on according to the
+ location.
+
+ 5. Save the drawing.
+
+ 6. Select all the slice rectangles. With the slice layer selected,
+ you can simply press Ctrl+A to select all rectangles. The status
+ bar should indicate that 9 rectangles are selected.
+
+ 7. Click the layer hide icon for the slice layer in the layer
+ palette. The rectangles will remain selected, even though they
+ are hidden.
+
+ 8. Choose File | Export Bitmap and check the *Batch export 9 selected
+ objects* box. Make sure that *Hide all except selected* is
+ unchecked. click *Export*. This will create PNG files in the same
+ directory as the drawing, named after the slices. These can now
+ be used for a styled box in a GRUB theme.
+
+6.3 Theme File Manual
+=====================
+
+The theme file is a plain text file. Lines that begin with "#" are
+ignored and considered comments. (Note: This may not be the case if
+the previous line ended where a value was expected.)
+
+ The theme file contains two types of statements:
+ 1. Global properties.
+
+ 2. Component construction.
+
+6.3.1 Global Properties
+-----------------------
+
+6.3.2 Format
+------------
+
+Global properties are specified with the simple format:
+ * name1: value1
+
+ * name2: "value which may contain spaces"
+
+ * name3: #88F
+
+ In this example, name3 is assigned a color value.
+
+6.3.3 Global Property List
+--------------------------
+
+title-text Specifies the text to display at the top
+ center of the screen as a title.
+title-font Defines the font used for the title
+ message at the top of the screen.
+title-color Defines the color of the title message.
+message-font Defines the font used for messages, such
+ as when GRUB is unable to automatically
+ boot an entry.
+message-color Defines the color of the message text.
+message-bg-color Defines the background color of the
+ message text area.
+desktop-image Specifies the image to use as the
+ background. It will be scaled to fit the
+ screen size.
+desktop-color Specifies the color for the background if
+ *desktop-image* is not specified.
+terminal-box Specifies the file name pattern for the
+ styled box slices used for the command
+ line terminal window. For example,
+ "terminal-box: terminal_*.png" will use
+ the images "terminal_c.png" as the center
+ area, "terminal_n.png" as the north (top)
+ edge, "terminal_nw.png" as the northwest
+ (upper left) corner, and so on. If the
+ image for any slice is not found, it will
+ simply be left empty.
+
+6.3.4 Component Construction
+----------------------------
+
+Greater customizability comes is provided by components. A tree of
+components forms the user interface. *Containers* are components that
+can contain other components, and there is always a single root
+component which is an instance of a *canvas* container.
+
+ Components are created in the theme file by prefixing the type of
+component with a '+' sign:
+
+ ` + label { text="GRUB" font="aqui 11" color="#8FF" } '
+
+ properties of a component are specified as "name = value" (whitespace
+surrounding tokens is optional and is ignored) where *value* may be:
+ * a single word (e.g., "align = center", "color = #FF8080"),
+
+ * a quoted string (e.g., "text = "Hello, World!""), or
+
+ * a tuple (e.g., "preferred_size = (120, 80)").
+
+6.3.5 Component List
+--------------------
+
+The following is a list of the components and the properties they
+support.
+
+ * label A label displays a line of text.
+
+ Properties:
+ text The text to display.
+ font The font to use for text display.
+ color The color of the text.
+ align The horizontal alignment of the text within
+ the component. Options are "left", "center",
+ and "right".
+
+ * image A component that displays an image. The image is scaled
+ to fit the component, although the preferred size defaults to
+ the image's original size unless the "preferred_size" property
+ is explicitly set.
+
+ Properties:
+
+ file The full path to the image file to load.
+
+ * progress_bar Displays a horizontally oriented progress bar. It
+ can be rendered using simple solid filled rectangles, or using
+ a pair of pixmap styled boxes.
+
+ Properties:
+
+ fg_color The foreground color for plain solid color
+ rendering.
+ bg_color The background color for plain solid color
+ rendering.
+ border_color The border color for plain solid color
+ rendering.
+ text_color The text color.
+ show_text Boolean value indicating whether or not text
+ should be displayed on the progress bar. If
+ set to *false*, then no text will be displayed
+ on the bar. If set to any other value, text
+ will be displayed on the bar.
+ bar_style The styled box specification for the frame of
+ the progress bar. Example:
+ "progress_frame_*.png"
+ highlight_styleThe styled box specification for the
+ highlighted region of the progress bar. This
+ box will be used to paint just the highlighted
+ region of the bar, and will be increased in
+ size as the bar nears completion. Example:
+ "progress_hl_*.png".
+ text The text to display on the progress bar. If
+ the progress bar's ID is set to "__timeout__",
+ then GRUB will updated this property with an
+ informative message as the timeout approaches.
+ value The progress bar current value. Normally not
+ set manually.
+ start The progress bar start value. Normally not
+ set manually.
+ end The progress bar end value. Normally not set
+ manually.
+
+ * circular_progress Displays a circular progress indicator. The
+ appearance of this component is determined by two images: the
+ *center* image and the *tick* image. The center image is
+ generally larger and will be drawn in the center of the
+ component. Around the circumference of a circle within the
+ component, the tick image will be drawn a certain number of
+ times, depending on the properties of the component.
+
+ Properties:
+
+ center_bitmap The file name of the image to draw in
+ the center of the component.
+ tick_bitmap The file name of the image to draw for
+ the tick marks.
+ num_ticks The number of ticks that make up a full
+ circle.
+ ticks_disappear Boolean value indicating whether tick
+ marks should progressively appear,
+ or progressively disappear as *value*
+ approaches *end*. Specify "true"
+ or "false".
+ value The progress indicator current value.
+ Normally not set manually.
+ start The progress indicator start value.
+ Normally not set manually.
+ end The progress indicator end value.
+ Normally not set manually.
+
+ * boot_menu Displays the GRUB boot menu. It allows selecting
+ items and executing them.
+
+ Properties:
+
+ item_font The font to use for the menu item
+ titles.
+ selected_item_font The font to use for the selected
+ menu item, or "inherit" (the
+ default) to use "item_font"
+ for the selected menu item as
+ well.
+ item_color The color to use for the menu
+ item titles.
+ selected_item_color The color to use for the selected
+ menu item, or "inherit" (the
+ default) to use
+ "item_color" for the selected
+ menu item as well.
+ icon_width The width of menu item icons.
+ Icons are scaled to the specified
+ size.
+ icon_height The height of menu item icons.
+ item_height The height of each menu item in
+ pixels.
+ item_padding The amount of space in pixels to
+ leave on each side of the menu
+ item contents.
+ item_icon_space The space between an item's icon
+ and the title text, in pixels.
+ item_spacing The amount of space to leave
+ between menu items, in pixels.
+ menu_pixmap_style The image file pattern for the
+ menu frame styled box.
+ Example: "menu_*.png" (this will
+ use images such as "menu_c.png",
+ "menu_w.png", `menu_nw.png",
+ etc.)
+ selected_item_pixmap_style The image file pattern for the
+ selected item highlight styled
+ box.
+ scrollbar Boolean value indicating whether
+ the scroll bar should be drawn if
+ the frame and thumb styled
+ boxes are configured.
+ scrollbar_frame The image file pattern for the
+ entire scroll bar.
+ Example: "scrollbar_*.png"
+ scrollbar_thumb The image file pattern for the
+ scroll bar thumb (the part of the
+ scroll bar that moves as
+ scrolling occurs).
+ Example: "scrollbar_thumb_*.png"
+ max_items_shown The maximum number of items to
+ show on the menu. If there are
+ more than *max_items_shown*
+ items in the menu, the list will
+ scroll to make all items
+ accessible.
+
+ * canvas Canvas is a container that allows manual placement of
+ components within it. It does not alter the positions of its
+ child components. It assigns all child components their
+ preferred sizes.
+
+ * hbox The *hbox* container lays out its children from left to
+ right, giving each one its preferred width. The height of each
+ child is set to the maximum of the preferred heights of all
+ children.
+
+ * vbox The *vbox* container lays out its children from top to
+ bottom, giving each one its preferred height. The width of
+ each child is set to the maximum of the preferred widths of all
+ children.
+
+6.3.6 Common properties
+-----------------------
+
+The following properties are supported by all components:
+`left'
+ The distance from the left border of container to left border of
+ the object in either of three formats:
+ x Value in pixels
+ p% Percentage
+ p%+x mixture of both
+
+`top'
+ The distance from the left border of container to left border of
+ the object in same format.
+
+`width'
+ The width of object in same format.
+
+`height'
+ The height of object in same format.
+
+`id'
+ The identifier for the component. This can be any arbitrary
+ string. The ID can be used by scripts to refer to various
+ components in the GUI component tree. Currently, there is one
+ special ID value that GRUB recognizes:
+
+ "__timeout__" Any component with this ID will have its
+ *text*, *start*, *end*, *value*, and *visible*
+ properties set by GRUB when it is counting
+ down to an automatic boot of the default menu
+ entry.
+
+
+File: grub.info, Node: Network, Next: Serial terminal, Prev: Theme file format, Up: Top
+
+7 Booting GRUB from the network
+*******************************
+
+The following instructions only work on PC BIOS systems where the
+Preboot eXecution Environment (PXE) is available.
+
+ To generate a PXE boot image, run:
+
+ grub-mkimage --format=i386-pc-pxe --output=grub.pxe --prefix='(pxe)/boot/grub' pxe pxecmd
+
+ Copy `grub.pxe', `/boot/grub/*.mod', and `/boot/grub/*.lst' to the
+PXE (TFTP) server, ensuring that `*.mod' and `*.lst' are accessible via
+the `/boot/grub/' path from the TFTP server root. Set the DHCP server
+configuration to offer `grub.pxe' as the boot file (the `filename'
+option in ISC dhcpd).
+
+ You can also use the `grub-mknetdir' utility to generate an image
+and a GRUB directory tree, rather than copying files around manually.
+
+ After GRUB has started, files on the TFTP server will be accessible
+via the `(pxe)' device.
+
+ The server and gateway IP address can be controlled by changing the
+`(pxe)' device name to `(pxe:SERVER-IP)' or
+`(pxe:SERVER-IP:GATEWAY-IP)'. Note that this should be changed both in
+the prefix and in any references to the device name in the
+configuration file.
+
+ GRUB provides several environment variables which may be used to
+inspect or change the behaviour of the PXE device:
+
+`net_pxe_ip'
+ The IP address of this machine. Read-only.
+
+`net_pxe_mac'
+ The network interface's MAC address. Read-only.
+
+`net_pxe_hostname'
+ The client host name provided by DHCP. Read-only.
+
+`net_pxe_domain'
+ The client domain name provided by DHCP. Read-only.
+
+`net_pxe_rootpath'
+ The path to the client's root disk provided by DHCP. Read-only.
+
+`net_pxe_extensionspath'
+ The path to additional DHCP vendor extensions provided by DHCP.
+ Read-only.
+
+`net_pxe_boot_file'
+ The boot file name provided by DHCP. Read-only.
+
+`net_pxe_dhcp_server_name'
+ The name of the DHCP server responsible for these boot parameters.
+ Read-only.
+
+`pxe_blksize'
+ The PXE transfer block size. Read-write, defaults to 512.
+
+`pxe_default_server'
+ The default PXE server. Read-write, although setting this is only
+ useful before opening a PXE device.
+
+`pxe_default_gateway'
+ The default gateway to use when contacting the PXE server.
+ Read-write, although setting this is only useful before opening a
+ PXE device.
+
+
+File: grub.info, Node: Serial terminal, Next: Vendor power-on keys, Prev: Network, Up: Top
+
+8 Using GRUB via a serial line
+******************************
+
+This chapter describes how to use the serial terminal support in GRUB.
+
+ If you have many computers or computers with no display/keyboard, it
+could be very useful to control the computers through serial
+communications. To connect one computer with another via a serial line,
+you need to prepare a null-modem (cross) serial cable, and you may need
+to have multiport serial boards, if your computer doesn't have extra
+serial ports. In addition, a terminal emulator is also required, such as
+minicom. Refer to a manual of your operating system, for more
+information.
+
+ As for GRUB, the instruction to set up a serial terminal is quite
+simple. Here is an example:
+
+ grub> serial --unit=0 --speed=9600
+ grub> terminal_input serial; terminal_output serial
+
+ The command `serial' initializes the serial unit 0 with the speed
+9600bps. The serial unit 0 is usually called `COM1', so, if you want to
+use COM2, you must specify `--unit=1' instead. This command accepts
+many other options, so please refer to *note serial::, for more details.
+
+ The commands `terminal_input' (*note terminal_input::) and
+`terminal_output' (*note terminal_output::) choose which type of
+terminal you want to use. In the case above, the terminal will be a
+serial terminal, but you can also pass `console' to the command, as
+`terminal_input serial console'. In this case, a terminal in which you
+press any key will be selected as a GRUB terminal. In the example above,
+note that you need to put both commands on the same command line, as you
+will lose the ability to type commands on the console after the first
+command.
+
+ However, note that GRUB assumes that your terminal emulator is
+compatible with VT100 by default. This is true for most terminal
+emulators nowadays, but you should pass the option `--dumb' to the
+command if your terminal emulator is not VT100-compatible or implements
+few VT100 escape sequences. If you specify this option then GRUB
+provides you with an alternative menu interface, because the normal
+menu requires several fancy features of your terminal.
+
+
+File: grub.info, Node: Vendor power-on keys, Next: Images, Prev: Serial terminal, Up: Top
+
+9 Using GRUB with vendor power-on keys
+**************************************
+
+Some laptop vendors provide an additional power-on button which boots
+another OS. GRUB supports such buttons with the `GRUB_TIMEOUT_BUTTON',
+`GRUB_DEFAULT_BUTTON', `GRUB_HIDDEN_TIMEOUT_BUTTON' and
+`GRUB_BUTTON_CMOS_ADDRESS' variables in default/grub (*note Simple
+configuration::). `GRUB_TIMEOUT_BUTTON', `GRUB_DEFAULT_BUTTON' and
+`GRUB_HIDDEN_TIMEOUT_BUTTON' are used instead of the corresponding
+variables without the `_BUTTON' suffix when powered on using the special
+button. `GRUB_BUTTON_CMOS_ADDRESS' is vendor-specific and partially
+model-specific. Values known to the GRUB team are:
+
+<Dell XPS M1530>
+ 85:3
+
+<Asus EeePC 1005PE>
+ 84:1 (unconfirmed)
+
+ To take full advantage of this function, install GRUB into the MBR
+(*note Installing GRUB using grub-install::).
+
+ If you have a laptop which has a similar feature and not in the
+above list could you figure your address and contribute? To discover
+the address do the following:
+ * boot normally
+
+ * sudo modprobe nvram
+ sudo cat /dev/nvram | xxd > normal_button.txt
+
+ * boot using vendor button
+
+ * sudo modprobe nvram
+ sudo cat /dev/nvram | xxd > normal_vendor.txt
+
+ Then compare these text files and find where a bit was toggled. E.g.
+in case of Dell XPS it was:
+ byte 0x47: 20 --> 28
+ It's a bit number 3 as seen from following table:
+0 01
+1 02
+2 04
+3 08
+4 10
+5 20
+6 40
+7 80
+
+ 0x47 is decimal 71. Linux nvram implementation cuts first 14 bytes of
+CMOS. So the real byte address in CMOS is 71+14=85 So complete address
+is 85:3
+
+
+File: grub.info, Node: Images, Next: Filesystem, Prev: Vendor power-on keys, Up: Top
+
+10 GRUB image files
+*******************
+
+GRUB consists of several images: a variety of bootstrap images for
+starting GRUB in various ways, a kernel image, and a set of modules
+which are combined with the kernel image to form a core image. Here is
+a short overview of them.
+
+`boot.img'
+ On PC BIOS systems, this image is the first part of GRUB to start.
+ It is written to a master boot record (MBR) or to the boot sector
+ of a partition. Because a PC boot sector is 512 bytes, the size
+ of this image is exactly 512 bytes.
+
+ The sole function of `boot.img' is to read the first sector of the
+ core image from a local disk and jump to it. Because of the size
+ restriction, `boot.img' cannot understand any file system
+ structure, so `grub-setup' hardcodes the location of the first
+ sector of the core image into `boot.img' when installing GRUB.
+
+`diskboot.img'
+ This image is used as the first sector of the core image when
+ booting from a hard disk. It reads the rest of the core image
+ into memory and starts the kernel. Since file system handling is
+ not yet available, it encodes the location of the core image using
+ a block list format.
+
+`cdboot.img'
+ This image is used as the first sector of the core image when
+ booting from a CD-ROM drive. It performs a similar function to
+ `diskboot.img'.
+
+`pxeboot.img'
+ This image is used as the start of the core image when booting
+ from the network using PXE. *Note Network::.
+
+`lnxboot.img'
+ This image may be placed at the start of the core image in order
+ to make GRUB look enough like a Linux kernel that it can be booted
+ by LILO using an `image=' section.
+
+`kernel.img'
+ This image contains GRUB's basic run-time facilities: frameworks
+ for device and file handling, environment variables, the rescue
+ mode command-line parser, and so on. It is rarely used directly,
+ but is built into all core images.
+
+`core.img'
+ This is the core image of GRUB. It is built dynamically from the
+ kernel image and an arbitrary list of modules by the `grub-mkimage'
+ program. Usually, it contains enough modules to access
+ `/boot/grub', and loads everything else (including menu handling,
+ the ability to load target operating systems, and so on) from the
+ file system at run-time. The modular design allows the core image
+ to be kept small, since the areas of disk where it must be
+ installed are often as small as 32KB.
+
+ *Note BIOS installation::, for details on where the core image can
+ be installed on PC systems.
+
+`*.mod'
+ Everything else in GRUB resides in dynamically loadable modules.
+ These are often loaded automatically, or built into the core image
+ if they are essential, but may also be loaded manually using the
+ `insmod' command (*note insmod::).
+
+For GRUB Legacy users
+=====================
+
+GRUB 2 has a different design from GRUB Legacy, and so correspondences
+with the images it used cannot be exact. Nevertheless, GRUB Legacy
+users often ask questions in the terms they are familiar with, and so
+here is a brief guide to how GRUB 2's images relate to that.
+
+`stage1'
+ Stage 1 from GRUB Legacy was very similar to `boot.img' in GRUB 2,
+ and they serve the same function.
+
+`*_stage1_5'
+ In GRUB Legacy, Stage 1.5's function was to include enough
+ filesystem code to allow the much larger Stage 2 to be read from
+ an ordinary filesystem. In this respect, its function was similar
+ to `core.img' in GRUB 2. However, `core.img' is much more capable
+ than Stage 1.5 was; since it offers a rescue shell, it is
+ sometimes possible to recover manually in the event that it is
+ unable to load any other modules, for example if partition numbers
+ have changed. `core.img' is built in a more flexible way,
+ allowing GRUB 2 to support reading modules from advanced disk
+ types such as LVM and RAID.
+
+ GRUB Legacy could run with only Stage 1 and Stage 2 in some limited
+ configurations, while GRUB 2 requires `core.img' and cannot work
+ without it.
+
+`stage2'
+ GRUB 2 has no single Stage 2 image. Instead, it loads modules from
+ `/boot/grub' at run-time.
+
+`stage2_eltorito'
+ In GRUB 2, images for booting from CD-ROM drives are now
+ constructed using `cdboot.img' and `core.img', making sure that
+ the core image contains the `iso9660' module. It is usually best
+ to use the `grub-mkrescue' program for this.
+
+`nbgrub'
+ There is as yet no equivalent for `nbgrub' in GRUB 2; it was used
+ by Etherboot and some other network boot loaders.
+
+`pxegrub'
+ In GRUB 2, images for PXE network booting are now constructed using
+ `pxeboot.img' and `core.img', making sure that the core image
+ contains the `pxe' and `pxecmd' modules. *Note Network::.
+
+
+File: grub.info, Node: Filesystem, Next: Interface, Prev: Images, Up: Top
+
+11 Filesystem syntax and semantics
+**********************************
+
+GRUB uses a special syntax for specifying disk drives which can be
+accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish
+between IDE, ESDI, SCSI, or others. You must know yourself which BIOS
+device is equivalent to which OS device. Normally, that will be clear if
+you see the files in a device or use the command `search' (*note
+search::).
+
+* Menu:
+
+* Device syntax:: How to specify devices
+* File name syntax:: How to specify files
+* Block list syntax:: How to specify block lists
+
+
+File: grub.info, Node: Device syntax, Next: File name syntax, Up: Filesystem
+
+11.1 How to specify devices
+===========================
+
+The device syntax is like this:
+
+ `(DEVICE[,PART-NUM][,BSD-SUBPART-LETTER])'
+
+ `[]' means the parameter is optional. DEVICE should be either `fd'
+or `hd' followed by a digit, like `fd0'. But you can also set DEVICE
+to a hexadecimal or a decimal number which is a BIOS drive number, so
+the following are equivalent:
+
+ (hd0)
+ (0x80)
+ (128)
+
+ PART-NUM represents the partition number of DEVICE, starting from
+one for primary partitions and from five for extended partitions, and
+BSD-SUBPART-LETTER represents the BSD disklabel subpartition, such as
+`a' or `e'.
+
+ A shortcut for specifying BSD subpartitions is
+`(DEVICE,BSD-SUBPART-LETTER)', in this case, GRUB searches for the
+first PC partition containing a BSD disklabel, then finds the
+subpartition BSD-SUBPART-LETTER. Here is an example:
+
+ (hd0,a)
+
+ The syntax `(hd0)' represents using the entire disk (or the MBR when
+installing GRUB), while the syntax `(hd0,1)' represents using the first
+partition of the disk (or the boot sector of the partition when
+installing GRUB).
+
+ If you enabled the network support, the special drive `(pxe)' is
+also available. Before using the network drive, you must initialize the
+network. *Note Network::, for more information.
+
+ If you boot GRUB from a CD-ROM, `(cd)' is available. *Note Making a
+GRUB bootable CD-ROM::, for details.
+
+
+File: grub.info, Node: File name syntax, Next: Block list syntax, Prev: Device syntax, Up: Filesystem
+
+11.2 How to specify files
+=========================
+
+There are two ways to specify files, by "absolute file name" and by
+"block list".
+
+ An absolute file name resembles a Unix absolute file name, using `/'
+for the directory separator (not `\' as in DOS). One example is
+`(hd0,1)/boot/grub/grub.cfg'. This means the file `/boot/grub/grub.cfg'
+in the first partition of the first hard disk. If you omit the device
+name in an absolute file name, GRUB uses GRUB's "root device"
+implicitly. So if you set the root device to, say, `(hd1,1)' by the
+command `set root=(hd1,1)' (*note set::), then `/boot/kernel' is the
+same as `(hd1,1)/boot/kernel'.
+
+
+File: grub.info, Node: Block list syntax, Prev: File name syntax, Up: Filesystem
+
+11.3 How to specify block lists
+===============================
+
+A block list is used for specifying a file that doesn't appear in the
+filesystem, like a chainloader. The syntax is
+`[OFFSET]+LENGTH[,[OFFSET]+LENGTH]...'. Here is an example:
+
+ `0+100,200+1,300+300'
+
+ This represents that GRUB should read blocks 0 through 99, block 200,
+and blocks 300 through 599. If you omit an offset, then GRUB assumes
+the offset is zero.
+
+ Like the file name syntax (*note File name syntax::), if a blocklist
+does not contain a device name, then GRUB uses GRUB's "root device". So
+`(hd0,2)+1' is the same as `+1' when the root device is `(hd0,2)'.
+
+
+File: grub.info, Node: Interface, Next: Environment, Prev: Filesystem, Up: Top
+
+12 GRUB's user interface
+************************
+
+GRUB has both a simple menu interface for choosing preset entries from a
+configuration file, and a highly flexible command-line for performing
+any desired combination of boot commands.
+
+ GRUB looks for its configuration file as soon as it is loaded. If one
+is found, then the full menu interface is activated using whatever
+entries were found in the file. If you choose the "command-line" menu
+option, or if the configuration file was not found, then GRUB drops to
+the command-line interface.
+
+* Menu:
+
+* Command-line interface:: The flexible command-line interface
+* Menu interface:: The simple menu interface
+* Menu entry editor:: Editing a menu entry
+
+
+File: grub.info, Node: Command-line interface, Next: Menu interface, Up: Interface
+
+12.1 The flexible command-line interface
+========================================
+
+The command-line interface provides a prompt and after it an editable
+text area much like a command-line in Unix or DOS. Each command is
+immediately executed after it is entered(1) (*note Command-line
+interface-Footnote-1::). The commands (*note Command-line and menu
+entry commands::) are a subset of those available in the configuration
+file, used with exactly the same syntax.
+
+ Cursor movement and editing of the text on the line can be done via a
+subset of the functions available in the Bash shell:
+
+<C-f>
+<PC right key>
+ Move forward one character.
+
+<C-b>
+<PC left key>
+ Move back one character.
+
+<C-a>
+<HOME>
+ Move to the start of the line.
+
+<C-e>
+<END>
+ Move the the end of the line.
+
+<C-d>
+<DEL>
+ Delete the character underneath the cursor.
+
+<C-h>
+<BS>
+ Delete the character to the left of the cursor.
+
+<C-k>
+ Kill the text from the current cursor position to the end of the
+ line.
+
+<C-u>
+ Kill backward from the cursor to the beginning of the line.
+
+<C-y>
+ Yank the killed text back into the buffer at the cursor.
+
+<C-p>
+<PC up key>
+ Move up through the history list.
+
+<C-n>
+<PC down key>
+ Move down through the history list.
+
+ When typing commands interactively, if the cursor is within or before
+the first word in the command-line, pressing the <TAB> key (or <C-i>)
+will display a listing of the available commands, and if the cursor is
+after the first word, the `<TAB>' will provide a completion listing of
+disks, partitions, and file names depending on the context. Note that
+to obtain a list of drives, one must open a parenthesis, as `root ('.
+
+ Note that you cannot use the completion functionality in the TFTP
+filesystem. This is because TFTP doesn't support file name listing for
+the security.
+
+
+File: grub.info, Node: Command-line interface-Footnotes, Up: Command-line interface
+
+ (1) However, this behavior will be changed in the future version, in
+a user-invisible way.
+
+
+File: grub.info, Node: Menu interface, Next: Menu entry editor, Prev: Command-line interface, Up: Interface
+
+12.2 The simple menu interface
+==============================
+
+The menu interface is quite easy to use. Its commands are both
+reasonably intuitive and described on screen.
+
+ Basically, the menu interface provides a list of "boot entries" to
+the user to choose from. Use the arrow keys to select the entry of
+choice, then press <RET> to run it. An optional timeout is available
+to boot the default entry (the first one if not set), which is aborted
+by pressing any key.
+
+ Commands are available to enter a bare command-line by pressing <c>
+(which operates exactly like the non-config-file version of GRUB, but
+allows one to return to the menu if desired by pressing <ESC>) or to
+edit any of the "boot entries" by pressing <e>.
+
+ If you protect the menu interface with a password (*note Security::),
+all you can do is choose an entry by pressing <RET>, or press <p> to
+enter the password.
+
+
+File: grub.info, Node: Menu entry editor, Prev: Menu interface, Up: Interface
+
+12.3 Editing a menu entry
+=========================
+
+The menu entry editor looks much like the main menu interface, but the
+lines in the menu are individual commands in the selected entry instead
+of entry names.
+
+ If an <ESC> is pressed in the editor, it aborts all the changes made
+to the configuration entry and returns to the main menu interface.
+
+ Each line in the menu entry can be edited freely, and you can add
+new lines by pressing <RET> at the end of a line. To boot the edited
+entry, press <Ctrl-x>.
+
+ Although GRUB unfortunately does not support "undo", you can do
+almost the same thing by just returning to the main menu using <ESC>.
+
+
+File: grub.info, Node: Environment, Next: Commands, Prev: Interface, Up: Top
+
+13 GRUB environment variables
+*****************************
+
+GRUB supports environment variables which are rather like those offered
+by all Unix-like systems. Environment variables have a name, which is
+unique and is usually a short identifier, and a value, which is an
+arbitrary string of characters. They may be set (*note set::), unset
+(*note unset::), or looked up (*note Shell-like scripting::) by name.
+
+ A number of environment variables have special meanings to various
+parts of GRUB. Others may be used freely in GRUB configuration files.
+
+* Menu:
+
+* Special environment variables::
+* Environment block::
+
+
+File: grub.info, Node: Special environment variables, Next: Environment block, Up: Environment
+
+13.1 Special environment variables
+==================================
+
+These variables have special meaning to GRUB.
+
+* Menu:
+
+* biosnum::
+* chosen::
+* color_highlight::
+* color_normal::
+* debug::
+* default::
+* fallback::
+* gfxmode::
+* gfxpayload::
+* gfxterm_font::
+* icondir::
+* lang::
+* locale_dir::
+* menu_color_highlight::
+* menu_color_normal::
+* net_pxe_boot_file::
+* net_pxe_dhcp_server_name::
+* net_pxe_domain::
+* net_pxe_extensionspath::
+* net_pxe_hostname::
+* net_pxe_ip::
+* net_pxe_mac::
+* net_pxe_rootpath::
+* pager::
+* prefix::
+* pxe_blksize::
+* pxe_default_gateway::
+* pxe_default_server::
+* root::
+* superusers::
+* theme::
+* timeout::
+
+
+File: grub.info, Node: biosnum, Next: chosen, Up: Special environment variables
+
+13.1.1 biosnum
+--------------
+
+When chain-loading another boot loader (*note Chain-loading::), GRUB may
+need to know what BIOS drive number corresponds to the root device
+(*note root::) so that it can set up registers properly. If the
+BIOSNUM variable is set, it overrides GRUB's own means of guessing this.
+
+ For an alternative approach which also changes BIOS drive mappings
+for the chain-loaded system, *note drivemap::.
+
+
+File: grub.info, Node: chosen, Next: color_highlight, Prev: biosnum, Up: Special environment variables
+
+13.1.2 chosen
+-------------
+
+When executing a menu entry, GRUB sets the CHOSEN variable to the title
+of the entry being executed.
+
+ If the menu entry is in one or more submenus, then CHOSEN is set to
+the titles of each of the submenus starting from the top level followed
+by the title of the menu entry itself, separated by `>'.
+
+
+File: grub.info, Node: color_highlight, Next: color_normal, Prev: chosen, Up: Special environment variables
+
+13.1.3 color_highlight
+----------------------
+
+This variable contains the "highlight" foreground and background
+terminal colors, separated by a slash (`/'). Setting this variable
+changes those colors. For the available color names, *note
+color_normal::.
+
+ The default is `black/white'.
+
+
+File: grub.info, Node: color_normal, Next: debug, Prev: color_highlight, Up: Special environment variables
+
+13.1.4 color_normal
+-------------------
+
+This variable contains the "normal" foreground and background terminal
+colors, separated by a slash (`/'). Setting this variable changes
+those colors. Each color must be a name from the following list:
+
+ * black
+
+ * blue
+
+ * green
+
+ * cyan
+
+ * red
+
+ * magenta
+
+ * brown
+
+ * light-gray
+
+ * dark-gray
+
+ * light-blue
+
+ * light-green
+
+ * light-cyan
+
+ * light-red
+
+ * light-magenta
+
+ * yellow
+
+ * white
+
+ The default is `white/black'.
+
+
+File: grub.info, Node: debug, Next: default, Prev: color_normal, Up: Special environment variables
+
+13.1.5 debug
+------------
+
+This variable may be set to enable debugging output from various
+components of GRUB. The value is a list of debug facility names
+separated by whitespace or `,', or `all' to enable all available
+debugging output.
+
+
+File: grub.info, Node: default, Next: fallback, Prev: debug, Up: Special environment variables
+
+13.1.6 default
+--------------
+
+If this variable is set, it identifies a menu entry that should be
+selected by default, possibly after a timeout (*note timeout::). The
+entry may be identified by number or by title.
+
+ If the entry is in a submenu, then it must be identified using the
+titles of each of the submenus starting from the top level followed by
+the number or title of the menu entry itself, separated by `>'. For
+example, take the following menu structure:
+
+ Submenu 1
+ Menu Entry 1
+ Menu Entry 2
+ Submenu 2
+ Submenu 3
+ Menu Entry 3
+ Menu Entry 4
+ Menu Entry 5
+
+ "Menu Entry 3" would then be identified as `Submenu 2>Submenu 3>Menu
+Entry 3'.
+
+ This variable is often set by `GRUB_DEFAULT' (*note Simple
+configuration::), `grub-set-default', or `grub-reboot'.
+
+
+File: grub.info, Node: fallback, Next: gfxmode, Prev: default, Up: Special environment variables
+
+13.1.7 fallback
+---------------
+
+If this variable is set, it identifies a menu entry that should be
+selected if the default menu entry fails to boot. Entries are
+identified in the same way as for `default' (*note default::).
+
+
+File: grub.info, Node: gfxmode, Next: gfxpayload, Prev: fallback, Up: Special environment variables
+
+13.1.8 gfxmode
+--------------
+
+If this variable is set, it sets the resolution used on the `gfxterm'
+graphical terminal. Note that you can only use modes which your
+graphics card supports via VESA BIOS Extensions (VBE), so for example
+native LCD panel resolutions may not be available. The default is
+`auto', which selects a platform-specific default that should look
+reasonable.
+
+ The resolution may be specified as a sequence of one or more modes,
+separated by commas (`,') or semicolons (`;'); each will be tried in
+turn until one is found. Each mode should be either `auto',
+`WIDTHxHEIGHT', or `WIDTHxHEIGHTxDEPTH'.
+
+
+File: grub.info, Node: gfxpayload, Next: gfxterm_font, Prev: gfxmode, Up: Special environment variables
+
+13.1.9 gfxpayload
+-----------------
+
+If this variable is set, it controls the video mode in which the Linux
+kernel starts up, replacing the `vga=' boot option (*note linux::). It
+may be set to `text' to force the Linux kernel to boot in normal text
+mode, `keep' to preserve the graphics mode set using `gfxmode', or any
+of the permitted values for `gfxmode' to set a particular graphics mode
+(*note gfxmode::).
+
+ Depending on your kernel, your distribution, your graphics card, and
+the phase of the moon, note that using this option may cause GNU/Linux
+to suffer from various display problems, particularly during the early
+part of the boot sequence. If you have problems, set this variable to
+`text' and GRUB will tell Linux to boot in normal text mode.
+
+ The default is platform-specific. On platforms with a native text
+mode (such as PC BIOS platforms), the default is `text'. Otherwise the
+default may be `auto' or a specific video mode.
+
+ This variable is often set by `GRUB_GFXPAYLOAD_LINUX' (*note Simple
+configuration::).
+
+
+File: grub.info, Node: gfxterm_font, Next: icondir, Prev: gfxpayload, Up: Special environment variables
+
+13.1.10 gfxterm_font
+--------------------
+
+If this variable is set, it names a font to use for text on the
+`gfxterm' graphical terminal. Otherwise, `gfxterm' may use any
+available font.
+
+
+File: grub.info, Node: icondir, Next: lang, Prev: gfxterm_font, Up: Special environment variables
+
+13.1.11 icondir
+---------------
+
+If this variable is set, it names a directory in which the GRUB
+graphical menu should look for icons after looking in the theme's
+`icons' directory. *Note Theme file format::.
+
+
+File: grub.info, Node: lang, Next: locale_dir, Prev: icondir, Up: Special environment variables
+
+13.1.12 lang
+------------
+
+If this variable is set, it names the language code that the `gettext'
+command (*note gettext::) uses to translate strings. For example,
+French would be named as `fr', and Simplified Chinese as `zh_CN'.
+
+ `grub-mkconfig' (*note Simple configuration::) will try to set a
+reasonable default for this variable based on the system locale.
+
+
+File: grub.info, Node: locale_dir, Next: menu_color_highlight, Prev: lang, Up: Special environment variables
+
+13.1.13 locale_dir
+------------------
+
+If this variable is set, it names the directory where translation files
+may be found (*note gettext::), usually `/boot/grub/locale'. Otherwise,
+internationalization is disabled.
+
+ `grub-mkconfig' (*note Simple configuration::) will set a reasonable
+default for this variable if internationalization is needed and any
+translation files are available.
+
+
+File: grub.info, Node: menu_color_highlight, Next: menu_color_normal, Prev: locale_dir, Up: Special environment variables
+
+13.1.14 menu_color_highlight
+----------------------------
+
+This variable contains the foreground and background colors to be used
+for the highlighted menu entry, separated by a slash (`/'). Setting
+this variable changes those colors. For the available color names,
+*note color_normal::.
+
+ The default is the value of `color_highlight' (*note
+color_highlight::).
+
+
+File: grub.info, Node: menu_color_normal, Next: net_pxe_boot_file, Prev: menu_color_highlight, Up: Special environment variables
+
+13.1.15 menu_color_normal
+-------------------------
+
+This variable contains the foreground and background colors to be used
+for non-highlighted menu entries, separated by a slash (`/'). Setting
+this variable changes those colors. For the available color names,
+*note color_normal::.
+
+ The default is the value of `color_normal' (*note color_normal::).
+
+
+File: grub.info, Node: net_pxe_boot_file, Next: net_pxe_dhcp_server_name, Prev: menu_color_normal, Up: Special environment variables
+
+13.1.16 net_pxe_boot_file
+-------------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: net_pxe_dhcp_server_name, Next: net_pxe_domain, Prev: net_pxe_boot_file, Up: Special environment variables
+
+13.1.17 net_pxe_dhcp_server_name
+--------------------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: net_pxe_domain, Next: net_pxe_extensionspath, Prev: net_pxe_dhcp_server_name, Up: Special environment variables
+
+13.1.18 net_pxe_domain
+----------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: net_pxe_extensionspath, Next: net_pxe_hostname, Prev: net_pxe_domain, Up: Special environment variables
+
+13.1.19 net_pxe_extensionspath
+------------------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: net_pxe_hostname, Next: net_pxe_ip, Prev: net_pxe_extensionspath, Up: Special environment variables
+
+13.1.20 net_pxe_hostname
+------------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: net_pxe_ip, Next: net_pxe_mac, Prev: net_pxe_hostname, Up: Special environment variables
+
+13.1.21 net_pxe_ip
+------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: net_pxe_mac, Next: net_pxe_rootpath, Prev: net_pxe_ip, Up: Special environment variables
+
+13.1.22 net_pxe_mac
+-------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: net_pxe_rootpath, Next: pager, Prev: net_pxe_mac, Up: Special environment variables
+
+13.1.23 net_pxe_rootpath
+------------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: pager, Next: prefix, Prev: net_pxe_rootpath, Up: Special environment variables
+
+13.1.24 pager
+-------------
+
+If set to `1', pause output after each screenful and wait for keyboard
+input. The default is not to pause output.
+
+
+File: grub.info, Node: prefix, Next: pxe_blksize, Prev: pager, Up: Special environment variables
+
+13.1.25 prefix
+--------------
+
+The location of the `/boot/grub' directory as an absolute file name
+(*note File name syntax::). This is normally set by GRUB at startup
+based on information provided by `grub-install'. GRUB modules are
+dynamically loaded from this directory, so it must be set correctly in
+order for many parts of GRUB to work.
+
+
+File: grub.info, Node: pxe_blksize, Next: pxe_default_gateway, Prev: prefix, Up: Special environment variables
+
+13.1.26 pxe_blksize
+-------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: pxe_default_gateway, Next: pxe_default_server, Prev: pxe_blksize, Up: Special environment variables
+
+13.1.27 pxe_default_gateway
+---------------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: pxe_default_server, Next: root, Prev: pxe_default_gateway, Up: Special environment variables
+
+13.1.28 pxe_default_server
+--------------------------
+
+*Note Network::.
+
+
+File: grub.info, Node: root, Next: superusers, Prev: pxe_default_server, Up: Special environment variables
+
+13.1.29 root
+------------
+
+The root device name (*note Device syntax::). Any file names that do
+not specify an explicit device name are read from this device. The
+default is normally set by GRUB at startup based on the value of
+`prefix' (*note prefix::).
+
+ For example, if GRUB was installed to the first partition of the
+first hard disk, then `prefix' might be set to `(hd0,msdos1)/boot/grub'
+and `root' to `hd0,msdos1'.
+
+
+File: grub.info, Node: superusers, Next: theme, Prev: root, Up: Special environment variables
+
+13.1.30 superusers
+------------------
+
+This variable may be set to a list of superuser names to enable
+authentication support. *Note Security::.
+
+
+File: grub.info, Node: theme, Next: timeout, Prev: superusers, Up: Special environment variables
+
+13.1.31 theme
+-------------
+
+This variable may be set to a directory containing a GRUB graphical menu
+theme. *Note Theme file format::.
+
+ This variable is often set by `GRUB_THEME' (*note Simple
+configuration::).
+
+
+File: grub.info, Node: timeout, Prev: theme, Up: Special environment variables
+
+13.1.32 timeout
+---------------
+
+If this variable is set, it specifies the time in seconds to wait for
+keyboard input before booting the default menu entry. A timeout of `0'
+means to boot the default entry immediately without displaying the
+menu; a timeout of `-1' (or unset) means to wait indefinitely.
+
+ This variable is often set by `GRUB_TIMEOUT' or
+`GRUB_HIDDEN_TIMEOUT' (*note Simple configuration::).
+
+
+File: grub.info, Node: Environment block, Prev: Special environment variables, Up: Environment
+
+13.2 The GRUB environment block
+===============================
+
+It is often useful to be able to remember a small amount of information
+from one boot to the next. For example, you might want to set the
+default menu entry based on what was selected the last time. GRUB
+deliberately does not implement support for writing files in order to
+minimise the possibility of the boot loader being responsible for file
+system corruption, so a GRUB configuration file cannot just create a
+file in the ordinary way. However, GRUB provides an "environment
+block" which can be used to save a small amount of state.
+
+ The environment block is a preallocated 1024-byte file, which
+normally lives in `/boot/grub/grubenv' (although you should not assume
+this). At boot time, the `load_env' command (*note load_env::) loads
+environment variables from it, and the `save_env' (*note save_env::)
+command saves environment variables to it. From a running system, the
+`grub-editenv' utility can be used to edit the environment block.
+
+ For safety reasons, this storage is only available when installed on
+a plain disk (no LVM or RAID), using a non-checksumming filesystem (no
+ZFS), and using BIOS or EFI functions (no ATA, USB or IEEE1275).
+
+ `grub-mkconfig' uses this facility to implement `GRUB_SAVEDEFAULT'
+(*note Simple configuration::).
+
+
+File: grub.info, Node: Commands, Next: Security, Prev: Environment, Up: Top
+
+14 The list of available commands
+*********************************
+
+In this chapter, we list all commands that are available in GRUB.
+
+ Commands belong to different groups. A few can only be used in the
+global section of the configuration file (or "menu"); most of them can
+be entered on the command-line and can be used either anywhere in the
+menu or specifically in the menu entries.
+
+ In rescue mode, only the `insmod' (*note insmod::), `ls' (*note
+ls::), `set' (*note set::), and `unset' (*note unset::) commands are
+normally available. If you end up in rescue mode and do not know what
+to do, then *note GRUB only offers a rescue shell::.
+
+* Menu:
+
+* Menu-specific commands::
+* General commands::
+* Command-line and menu entry commands::
+
+
+File: grub.info, Node: Menu-specific commands, Next: General commands, Up: Commands
+
+14.1 The list of commands for the menu only
+===========================================
+
+The semantics used in parsing the configuration file are the following:
+
+ * The files _must_ be in plain-text format.
+
+ * `#' at the beginning of a line in a configuration file means it is
+ only a comment.
+
+ * Options are separated by spaces.
+
+ * All numbers can be either decimal or hexadecimal. A hexadecimal
+ number must be preceded by `0x', and is case-insensitive.
+
+ These commands can only be used in the menu:
+
+* Menu:
+
+* menuentry:: Start a menu entry
+* submenu:: Group menu entries
+
+
+File: grub.info, Node: menuentry, Next: submenu, Up: Menu-specific commands
+
+14.1.1 menuentry
+----------------
+
+ -- Command: menuentry TITLE [`--class=class' ...] [`--users=users']
+ [`--hotkey=key'] { COMMAND; ... }
+ This defines a GRUB menu entry named TITLE. When this entry is
+ selected from the menu, GRUB will set the CHOSEN environment
+ variable to TITLE, execute the list of commands given within
+ braces, and if the last command in the list returned successfully
+ and a kernel was loaded it will execute the `boot' command.
+
+ The `--class' option may be used any number of times to group menu
+ entries into classes. Menu themes may display different classes
+ using different styles.
+
+ The `--users' option grants specific users access to specific menu
+ entries. *Note Security::.
+
+ The `--hotkey' option associates a hotkey with a menu entry. KEY
+ may be a single letter, or one of the aliases `backspace', `tab',
+ or `delete'.
+
+
+File: grub.info, Node: submenu, Prev: menuentry, Up: Menu-specific commands
+
+14.1.2 submenu
+--------------
+
+ -- Command: submenu TITLE [`--class=class' ...] [`--users=users']
+ [`--hotkey=key'] { MENU ENTRIES ... }
+ This defines a submenu. An entry called TITLE will be added to the
+ menu; when that entry is selected, a new menu will be displayed
+ showing all the entries within this submenu.
+
+ All options are the same as in the `menuentry' command (*note
+ menuentry::).
+
+
+File: grub.info, Node: General commands, Next: Command-line and menu entry commands, Prev: Menu-specific commands, Up: Commands
+
+14.2 The list of general commands
+=================================
+
+Commands usable anywhere in the menu and in the command-line.
+
+* Menu:
+
+* serial:: Set up a serial device
+* terminal_input:: Manage input terminals
+* terminal_output:: Manage output terminals
+* terminfo:: Define terminal type
+
+
+File: grub.info, Node: serial, Next: terminal_input, Up: General commands
+
+14.2.1 serial
+-------------
+
+ -- Command: serial [`--unit=unit'] [`--port=port'] [`--speed=speed']
+ [`--word=word'] [`--parity=parity'] [`--stop=stop']
+ Initialize a serial device. UNIT is a number in the range 0-3
+ specifying which serial port to use; default is 0, which
+ corresponds to the port often called COM1. PORT is the I/O port
+ where the UART is to be found; if specified it takes precedence
+ over UNIT. SPEED is the transmission speed; default is 9600. WORD
+ and STOP are the number of data bits and stop bits. Data bits must
+ be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data
+ bits and one stop bit. PARITY is one of `no', `odd', `even' and
+ defaults to `no'.
+
+ The serial port is not used as a communication channel unless the
+ `terminal_input' or `terminal_output' command is used (*note
+ terminal_input::, *note terminal_output::).
+
+ See also *note Serial terminal::.
+
+
+File: grub.info, Node: terminal_input, Next: terminal_output, Prev: serial, Up: General commands
+
+14.2.2 terminal_input
+---------------------
+
+ -- Command: terminal_input [`--append'|`--remove'] [terminal1]
+ [terminal2] ...
+ List or select an input terminal.
+
+ With no arguments, list the active and available input terminals.
+
+ With `--append', add the named terminals to the list of active
+ input terminals; any of these may be used to provide input to GRUB.
+
+ With `--remove', remove the named terminals from the active list.
+
+ With no options but a list of terminal names, make only the listed
+ terminal names active.
+
+
+File: grub.info, Node: terminal_output, Next: terminfo, Prev: terminal_input, Up: General commands
+
+14.2.3 terminal_output
+----------------------
+
+ -- Command: terminal_output [`--append'|`--remove'] [terminal1]
+ [terminal2] ...
+ List or select an output terminal.
+
+ With no arguments, list the active and available output terminals.
+
+ With `--append', add the named terminals to the list of active
+ output terminals; all of these will receive output from GRUB.
+
+ With `--remove', remove the named terminals from the active list.
+
+ With no options but a list of terminal names, make only the listed
+ terminal names active.
+
+
+File: grub.info, Node: terminfo, Prev: terminal_output, Up: General commands
+
+14.2.4 terminfo
+---------------
+
+ -- Command: terminfo [-a|-u|-v] [term]
+ Define the capabilities of your terminal by giving the name of an
+ entry in the terminfo database, which should correspond roughly to
+ a `TERM' environment variable in Unix.
+
+ The currently available terminal types are `vt100', `vt100-color',
+ `ieee1275', and `dumb'. If you need other terminal types, please
+ contact us to discuss the best way to include support for these in
+ GRUB.
+
+ The `-a' (`--ascii'), `-u' (`--utf8'), and `-v' (`--visual-utf8')
+ options control how non-ASCII text is displayed. `-a' specifies
+ an ASCII-only terminal; `-u' specifies logically-ordered UTF-8;
+ and `-v' specifies "visually-ordered UTF-8" (in other words,
+ arranged such that a terminal emulator without bidirectional text
+ support will display right-to-left text in the proper order; this
+ is not really proper UTF-8, but a workaround).
+
+ If no option or terminal type is specified, the current terminal
+ type is printed.
+
+
+File: grub.info, Node: Command-line and menu entry commands, Prev: General commands, Up: Commands
+
+14.3 The list of command-line and menu entry commands
+=====================================================
+
+These commands are usable in the command-line and in menu entries. If
+you forget a command, you can run the command `help' (*note help::).
+
+* Menu:
+
+* acpi:: Load ACPI tables
+* badram:: Filter out bad regions of RAM
+* blocklist:: Print a block list
+* boot:: Start up your operating system
+* cat:: Show the contents of a file
+* chainloader:: Chain-load another boot loader
+* cmp:: Compare two files
+* configfile:: Load a configuration file
+* cpuid:: Check for CPU features
+* crc:: Calculate CRC32 checksums
+* date:: Display or set current date and time
+* drivemap:: Map a drive to another
+* echo:: Display a line of text
+* export:: Export an environment variable
+* false:: Do nothing, unsuccessfully
+* gettext:: Translate a string
+* gptsync:: Fill an MBR based on GPT entries
+* halt:: Shut down your computer
+* help:: Show help messages
+* initrd:: Load a Linux initrd
+* initrd16:: Load a Linux initrd (16-bit mode)
+* insmod:: Insert a module
+* keystatus:: Check key modifier status
+* linux:: Load a Linux kernel
+* linux16:: Load a Linux kernel (16-bit mode)
+* list_env:: List variables in environment block
+* load_env:: Load variables from environment block
+* loopback:: Make a device from a filesystem image
+* ls:: List devices or files
+* normal:: Enter normal mode
+* normal_exit:: Exit from normal mode
+* parttool:: Modify partition table entries
+* password:: Set a clear-text password
+* password_pbkdf2:: Set a hashed password
+* play:: Play a tune
+* pxe_unload:: Unload the PXE environment
+* read:: Read user input
+* reboot:: Reboot your computer
+* save_env:: Save variables to environment block
+* search:: Search devices by file, label, or UUID
+* sendkey:: Emulate keystrokes
+* set:: Set an environment variable
+* true:: Do nothing, successfully
+* unset:: Unset an environment variable
+* uppermem:: Set the upper memory size
+
+
+File: grub.info, Node: acpi, Next: badram, Up: Command-line and menu entry commands
+
+14.3.1 acpi
+-----------
+
+ -- Command: acpi [`-1'|`-2']
+ [`--exclude=table1,...'|`--load-only=table1,...']
+ [`--oemid=id'] [`--oemtable=table'] [`--oemtablerev=rev']
+ [`--oemtablecreator=creator'] [`--oemtablecreatorrev=rev']
+ [`--no-ebda'] filename ...
+ Modern BIOS systems normally implement the Advanced Configuration
+ and Power Interface (ACPI), and define various tables that
+ describe the interface between an ACPI-compliant operating system
+ and the firmware. In some cases, the tables provided by default
+ only work well with certain operating systems, and it may be
+ necessary to replace some of them.
+
+ Normally, this command will replace the Root System Description
+ Pointer (RSDP) in the Extended BIOS Data Area to point to the new
+ tables. If the `--no-ebda' option is used, the new tables will be
+ known only to GRUB, but may be used by GRUB's EFI emulation.
+
+
+File: grub.info, Node: badram, Next: blocklist, Prev: acpi, Up: Command-line and menu entry commands
+
+14.3.2 badram
+-------------
+
+ -- Command: badram addr,mask[,addr,mask...]
+ Filter out bad RAM.
+
+ This command notifies the memory manager that specified regions of
+RAM ought to be filtered out (usually, because they're damaged). This
+remains in effect after a payload kernel has been loaded by GRUB, as
+long as the loaded kernel obtains its memory map from GRUB. Kernels
+that support this include Linux, GNU Mach, the kernel of FreeBSD and
+Multiboot kernels in general.
+
+ Syntax is the same as provided by the Memtest86+ utility
+(http://www.memtest.org/): a list of address/mask pairs. Given a
+page-aligned address and a base address / mask pair, if all the bits of
+the page-aligned address that are enabled by the mask match with the
+base address, it means this page is to be filtered. This syntax makes
+it easy to represent patterns that are often result of memory damage,
+due to physical distribution of memory cells.
+
+
+File: grub.info, Node: blocklist, Next: boot, Prev: badram, Up: Command-line and menu entry commands
+
+14.3.3 blocklist
+----------------
+
+ -- Command: blocklist file
+ Print a block list (*note Block list syntax::) for FILE.
+
+
+File: grub.info, Node: boot, Next: cat, Prev: blocklist, Up: Command-line and menu entry commands
+
+14.3.4 boot
+-----------
+
+ -- Command: boot
+ Boot the OS or chain-loader which has been loaded. Only necessary
+ if running the fully interactive command-line (it is implicit at
+ the end of a menu entry).
+
+
+File: grub.info, Node: cat, Next: chainloader, Prev: boot, Up: Command-line and menu entry commands
+
+14.3.5 cat
+----------
+
+ -- Command: cat [`--dos'] file
+ Display the contents of the file FILE. This command may be useful
+ to remind you of your OS's root partition:
+
+ grub> cat /etc/fstab
+
+ If the `--dos' option is used, then carriage return / new line
+ pairs will be displayed as a simple new line. Otherwise, the
+ carriage return will be displayed as a control character (`<d>')
+ to make it easier to see when boot problems are caused by a file
+ formatted using DOS-style line endings.
+
+
+File: grub.info, Node: chainloader, Next: cmp, Prev: cat, Up: Command-line and menu entry commands
+
+14.3.6 chainloader
+------------------
+
+ -- Command: chainloader [`--force'] file
+ Load FILE as a chain-loader. Like any other file loaded by the
+ filesystem code, it can use the blocklist notation (*note Block
+ list syntax::) to grab the first sector of the current partition
+ with `+1'. If you specify the option `--force', then load FILE
+ forcibly, whether it has a correct signature or not. This is
+ required when you want to load a defective boot loader, such as
+ SCO UnixWare 7.1.
+
+
+File: grub.info, Node: cmp, Next: configfile, Prev: chainloader, Up: Command-line and menu entry commands
+
+14.3.7 cmp
+----------
+
+ -- Command: cmp file1 file2
+ Compare the file FILE1 with the file FILE2. If they differ in
+ size, print the sizes like this:
+
+ Differ in size: 0x1234 [foo], 0x4321 [bar]
+
+ If the sizes are equal but the bytes at an offset differ, then
+ print the bytes like this:
+
+ Differ at the offset 777: 0xbe [foo], 0xef [bar]
+
+ If they are completely identical, nothing will be printed.
+
+
+File: grub.info, Node: configfile, Next: cpuid, Prev: cmp, Up: Command-line and menu entry commands
+
+14.3.8 configfile
+-----------------
+
+ -- Command: configfile file
+ Load FILE as a configuration file. If FILE defines any menu
+ entries, then show a menu containing them immediately.
+
+
+File: grub.info, Node: cpuid, Next: crc, Prev: configfile, Up: Command-line and menu entry commands
+
+14.3.9 cpuid
+------------
+
+ -- Command: cpuid [-l]
+ Check for CPU features. This command is only available on x86
+ systems.
+
+ With the `-l' option, return true if the CPU supports long mode
+ (64-bit).
+
+ If invoked without options, this command currently behaves as if
+ it had been invoked with `-l'. This may change in the future.
+
+
+File: grub.info, Node: crc, Next: date, Prev: cpuid, Up: Command-line and menu entry commands
+
+14.3.10 crc
+-----------
+
+ -- Command: crc file
+ Display the CRC32 checksum of FILE.
+
+
+File: grub.info, Node: date, Next: drivemap, Prev: crc, Up: Command-line and menu entry commands
+
+14.3.11 date
+------------
+
+ -- Command: date [[year-]month-day] [hour:minute[:second]]
+ With no arguments, print the current date and time.
+
+ Otherwise, take the current date and time, change any elements
+ specified as arguments, and set the result as the new date and
+ time. For example, `date 01-01' will set the current month and
+ day to January 1, but leave the year, hour, minute, and second
+ unchanged.
+
+
+File: grub.info, Node: drivemap, Next: echo, Prev: date, Up: Command-line and menu entry commands
+
+14.3.12 drivemap
+----------------
+
+ -- Command: drivemap `-l'|`-r'|[`-s'] from_drive to_drive
+ Without options, map the drive FROM_DRIVE to the drive TO_DRIVE.
+ This is necessary when you chain-load some operating systems, such
+ as DOS, if such an OS resides at a non-first drive. For
+ convenience, any partition suffix on the drive is ignored, so you
+ can safely use ${root} as a drive specification.
+
+ With the `-s' option, perform the reverse mapping as well, swapping
+ the two drives.
+
+ With the `-l' option, list the current mappings.
+
+ With the `-r' option, reset all mappings to the default values.
+
+ For example:
+
+ drivemap -s (hd0) (hd1)
+
+
+File: grub.info, Node: echo, Next: export, Prev: drivemap, Up: Command-line and menu entry commands
+
+14.3.13 echo
+------------
+
+ -- Command: echo [`-n'] [`-e'] string ...
+ Display the requested text and, unless the `-n' option is used, a
+ trailing new line. If there is more than one string, they are
+ separated by spaces in the output. As usual in GRUB commands,
+ variables may be substituted using `${var}'.
+
+ The `-e' option enables interpretation of backslash escapes. The
+ following sequences are recognised:
+
+ `\\'
+ backslash
+
+ `\a'
+ alert (BEL)
+
+ `\c'
+ suppress trailing new line
+
+ `\f'
+ form feed
+
+ `\n'
+ new line
+
+ `\r'
+ carriage return
+
+ `\t'
+ horizontal tab
+
+ `\v'
+ vertical tab
+
+ When interpreting backslash escapes, backslash followed by any
+ other character will print that character.
+
+
+File: grub.info, Node: export, Next: false, Prev: echo, Up: Command-line and menu entry commands
+
+14.3.14 export
+--------------
+
+ -- Command: export envvar
+ Export the environment variable ENVVAR. Exported variables are
+ visible to subsidiary configuration files loaded using
+ `configfile'.
+
+
+File: grub.info, Node: false, Next: gettext, Prev: export, Up: Command-line and menu entry commands
+
+14.3.15 false
+-------------
+
+ -- Command: false
+ Do nothing, unsuccessfully. This is mainly useful in control
+ constructs such as `if' and `while' (*note Shell-like scripting::).
+
+
+File: grub.info, Node: gettext, Next: gptsync, Prev: false, Up: Command-line and menu entry commands
+
+14.3.16 gettext
+---------------
+
+ -- Command: gettext string
+ Translate STRING into the current language.
+
+ The current language code is stored in the `lang' variable in
+ GRUB's environment (*note lang::). Translation files in MO format
+ are read from `locale_dir' (*note locale_dir::), usually
+ `/boot/grub/locale'.
+
+
+File: grub.info, Node: gptsync, Next: halt, Prev: gettext, Up: Command-line and menu entry commands
+
+14.3.17 gptsync
+---------------
+
+ -- Command: gptsync device [partition[+/-[type]]] ...
+ Disks using the GUID Partition Table (GPT) also have a legacy
+ Master Boot Record (MBR) partition table for compatibility with
+ the BIOS and with older operating systems. The legacy MBR can
+ only represent a limited subset of GPT partition entries.
+
+ This command populates the legacy MBR with the specified PARTITION
+ entries on DEVICE. Up to three partitions may be used.
+
+ TYPE is an MBR partition type code; prefix with `0x' if you want
+ to enter this in hexadecimal. The separator between PARTITION and
+ TYPE may be `+' to make the partition active, or `-' to make it
+ inactive; only one partition may be active. If both the separator
+ and type are omitted, then the partition will be inactive.
+
+
+File: grub.info, Node: halt, Next: help, Prev: gptsync, Up: Command-line and menu entry commands
+
+14.3.18 halt
+------------
+
+ -- Command: halt `--no-apm'
+ The command halts the computer. If the `--no-apm' option is
+ specified, no APM BIOS call is performed. Otherwise, the computer
+ is shut down using APM.
+
+
+File: grub.info, Node: help, Next: initrd, Prev: halt, Up: Command-line and menu entry commands
+
+14.3.19 help
+------------
+
+ -- Command: help [pattern ...]
+ Display helpful information about builtin commands. If you do not
+ specify PATTERN, this command shows short descriptions of all
+ available commands.
+
+ If you specify any PATTERNS, it displays longer information about
+ each of the commands whose names begin with those PATTERNS.
+
+
+File: grub.info, Node: initrd, Next: initrd16, Prev: help, Up: Command-line and menu entry commands
+
+14.3.20 initrd
+--------------
+
+ -- Command: initrd file
+ Load an initial ramdisk for a Linux kernel image, and set the
+ appropriate parameters in the Linux setup area in memory. This
+ may only be used after the `linux' command (*note linux::) has
+ been run. See also *note GNU/Linux::.
+
+
+File: grub.info, Node: initrd16, Next: insmod, Prev: initrd, Up: Command-line and menu entry commands
+
+14.3.21 initrd16
+----------------
+
+ -- Command: initrd16 file
+ Load an initial ramdisk for a Linux kernel image to be booted in
+ 16-bit mode, and set the appropriate parameters in the Linux setup
+ area in memory. This may only be used after the `linux16' command
+ (*note linux16::) has been run. See also *note GNU/Linux::.
+
+ This command is only available on x86 systems.
+
+
+File: grub.info, Node: insmod, Next: keystatus, Prev: initrd16, Up: Command-line and menu entry commands
+
+14.3.22 insmod
+--------------
+
+ -- Command: insmod module
+ Insert the dynamic GRUB module called MODULE.
+
+
+File: grub.info, Node: keystatus, Next: linux, Prev: insmod, Up: Command-line and menu entry commands
+
+14.3.23 keystatus
+-----------------
+
+ -- Command: keystatus [`--shift'] [`--ctrl'] [`--alt']
+ Return true if the Shift, Control, or Alt modifier keys are held
+ down, as requested by options. This is useful in scripting, to
+ allow some user control over behaviour without having to wait for
+ a keypress.
+
+ Checking key modifier status is only supported on some platforms.
+ If invoked without any options, the `keystatus' command returns
+ true if and only if checking key modifier status is supported.
+
+
+File: grub.info, Node: linux, Next: linux16, Prev: keystatus, Up: Command-line and menu entry commands
+
+14.3.24 linux
+-------------
+
+ -- Command: linux file ...
+ Load a Linux kernel image from FILE. The rest of the line is
+ passed verbatim as the "kernel command-line". Any initrd must be
+ reloaded after using this command (*note initrd::).
+
+ On x86 systems, the kernel will be booted using the 32-bit boot
+ protocol. Note that this means that the `vga=' boot option will
+ not work; if you want to set a special video mode, you will need
+ to use GRUB commands such as `set gfxpayload=1024x768' or `set
+ gfxpayload=keep' (to keep the same mode as used in GRUB) instead.
+ GRUB can automatically detect some uses of `vga=' and translate
+ them to appropriate settings of `gfxpayload'. The `linux16'
+ command (*note linux16::) avoids this restriction.
+
+
+File: grub.info, Node: linux16, Next: list_env, Prev: linux, Up: Command-line and menu entry commands
+
+14.3.25 linux16
+---------------
+
+ -- Command: linux16 file ...
+ Load a Linux kernel image from FILE in 16-bit mode. The rest of
+ the line is passed verbatim as the "kernel command-line". Any
+ initrd must be reloaded after using this command (*note
+ initrd16::).
+
+ The kernel will be booted using the traditional 16-bit boot
+ protocol. As well as bypassing problems with `vga=' described in
+ *note linux::, this permits booting some other programs that
+ implement the Linux boot protocol for the sake of convenience.
+
+ This command is only available on x86 systems.
+
+
+File: grub.info, Node: list_env, Next: load_env, Prev: linux16, Up: Command-line and menu entry commands
+
+14.3.26 list_env
+----------------
+
+ -- Command: list_env [`-f' file]
+ List all variables in the environment block file. *Note
+ Environment block::.
+
+ The `-f' option overrides the default location of the environment
+ block.
+
+
+File: grub.info, Node: load_env, Next: loopback, Prev: list_env, Up: Command-line and menu entry commands
+
+14.3.27 load_env
+----------------
+
+ -- Command: load_env [`-f' file]
+ Load all variables from the environment block file into the
+ environment. *Note Environment block::.
+
+ The `-f' option overrides the default location of the environment
+ block.
+
+
+File: grub.info, Node: loopback, Next: ls, Prev: load_env, Up: Command-line and menu entry commands
+
+14.3.28 loopback
+----------------
+
+ -- Command: loopback [`-d'] device file
+ Make the device named DEVICE correspond to the contents of the
+ filesystem image in FILE. For example:
+
+ loopback loop0 /path/to/image
+ ls (loop0)/
+
+ With the `-d' option, delete a device previously created using this
+ command.
+
+
+File: grub.info, Node: ls, Next: normal, Prev: loopback, Up: Command-line and menu entry commands
+
+14.3.29 ls
+----------
+
+ -- Command: ls [arg ...]
+ List devices or files.
+
+ With no arguments, print all devices known to GRUB.
+
+ If the argument is a device name enclosed in parentheses (*note
+ Device syntax::), then list all files at the root directory of
+ that device.
+
+ If the argument is a directory given as an absolute file name
+ (*note File name syntax::), then list the contents of that
+ directory.
+
+
+File: grub.info, Node: normal, Next: normal_exit, Prev: ls, Up: Command-line and menu entry commands
+
+14.3.30 normal
+--------------
+
+ -- Command: normal [file]
+ Enter normal mode and display the GRUB menu.
+
+ In normal mode, commands, filesystem modules, and cryptography
+ modules are automatically loaded, and the full GRUB script parser
+ is available. Other modules may be explicitly loaded using
+ `insmod' (*note insmod::).
+
+ If a FILE is given, then commands will be read from that file.
+ Otherwise, they will be read from `$prefix/grub.cfg' if it exists.
+
+ `normal' may be called from within normal mode, creating a nested
+ environment. It is more usual to use `configfile' (*note
+ configfile::) for this.
+
+
+File: grub.info, Node: normal_exit, Next: parttool, Prev: normal, Up: Command-line and menu entry commands
+
+14.3.31 normal_exit
+-------------------
+
+ -- Command: normal_exit
+ Exit normal mode (*note normal::). If this instance of normal
+ mode was not nested within another one, then return to rescue mode.
+
+
+File: grub.info, Node: parttool, Next: password, Prev: normal_exit, Up: Command-line and menu entry commands
+
+14.3.32 parttool
+----------------
+
+ -- Command: parttool partition commands
+ Make various modifications to partition table entries.
+
+ Each COMMAND is either a boolean option, in which case it must be
+ followed with `+' or `-' (with no intervening space) to enable or
+ disable that option, or else it takes a value in the form
+ `COMMAND=VALUE'.
+
+ Currently, `parttool' is only useful on DOS partition tables (also
+ known as Master Boot Record, or MBR). On these partition tables,
+ the following commands are available:
+
+ `boot' (boolean)
+ When enabled, this makes the selected partition be the active
+ (bootable) partition on its disk, clearing the active flag on
+ all other partitions. This command is limited to _primary_
+ partitions.
+
+ `type' (value)
+ Change the type of an existing partition. The value must be
+ a number in the range 0-0xFF (prefix with `0x' to enter it in
+ hexadecimal).
+
+ `hidden' (boolean)
+ When enabled, this hides the selected partition by setting
+ the "hidden" bit in its partition type code; when disabled,
+ unhides the selected partition by clearing this bit. This is
+ useful only when booting DOS or Wwindows and multiple primary
+ FAT partitions exist in one disk. See also *note
+ DOS/Windows::.
+
+
+File: grub.info, Node: password, Next: password_pbkdf2, Prev: parttool, Up: Command-line and menu entry commands
+
+14.3.33 password
+----------------
+
+ -- Command: password user clear-password
+ Define a user named USER with password CLEAR-PASSWORD. *Note
+ Security::.
+
+
+File: grub.info, Node: password_pbkdf2, Next: play, Prev: password, Up: Command-line and menu entry commands
+
+14.3.34 password_pbkdf2
+-----------------------
+
+ -- Command: password_pbkdf2 user hashed-password
+ Define a user named USER with password hash HASHED-PASSWORD. Use
+ `grub-mkpasswd-pbkdf2' (*note Invoking grub-mkpasswd-pbkdf2::) to
+ generate password hashes. *Note Security::.
+
+
+File: grub.info, Node: play, Next: pxe_unload, Prev: password_pbkdf2, Up: Command-line and menu entry commands
+
+14.3.35 play
+------------
+
+ -- Command: play file | tempo [pitch1 duration1] [pitch2 duration2] ...
+ Plays a tune
+
+ If the argument is a file name (*note File name syntax::), play
+ the tune recorded in it. The file format is first the tempo as an
+ unsigned 32bit little-endian number, then pairs of unsigned 16bit
+ little-endian numbers for pitch and duration pairs.
+
+ If the arguments are a series of numbers, play the inline tune.
+
+ The tempo is the base for all note durations. 60 gives a 1-second
+ base, 120 gives a half-second base, etc. Pitches are Hz. Set
+ pitch to 0 to produce a rest.
+
+
+File: grub.info, Node: pxe_unload, Next: read, Prev: play, Up: Command-line and menu entry commands
+
+14.3.36 pxe_unload
+------------------
+
+ -- Command: pxe_unload
+ Unload the PXE environment (*note Network::).
+
+ This command is only available on PC BIOS systems.
+
+
+File: grub.info, Node: read, Next: reboot, Prev: pxe_unload, Up: Command-line and menu entry commands
+
+14.3.37 read
+------------
+
+ -- Command: read [var]
+ Read a line of input from the user. If an environment variable
+ VAR is given, set that environment variable to the line of input
+ that was read, with no terminating newline.
+
+
+File: grub.info, Node: reboot, Next: save_env, Prev: read, Up: Command-line and menu entry commands
+
+14.3.38 reboot
+--------------
+
+ -- Command: reboot
+ Reboot the computer.
+
+
+File: grub.info, Node: save_env, Next: search, Prev: reboot, Up: Command-line and menu entry commands
+
+14.3.39 save_env
+----------------
+
+ -- Command: save_env [`-f' file] var ...
+ Save the named variables from the environment to the environment
+ block file. *Note Environment block::.
+
+ The `-f' option overrides the default location of the environment
+ block.
+
+
+File: grub.info, Node: search, Next: sendkey, Prev: save_env, Up: Command-line and menu entry commands
+
+14.3.40 search
+--------------
+
+ -- Command: search [`--file'|`--label'|`--fs-uuid'] [`--set' [var]]
+ [`--no-floppy'] name
+ Search devices by file (`-f', `--file'), filesystem label (`-l',
+ `--label'), or filesystem UUID (`-u', `--fs-uuid').
+
+ If the `--set' option is used, the first device found is set as the
+ value of environment variable VAR. The default variable is `root'.
+
+ The `--no-floppy' option prevents searching floppy devices, which
+ can be slow.
+
+ The `search.file', `search.fs_label', and `search.fs_uuid'
+ commands are aliases for `search --file', `search --label', and
+ `search --fs-uuid' respectively.
+
+
+File: grub.info, Node: sendkey, Next: set, Prev: search, Up: Command-line and menu entry commands
+
+14.3.41 sendkey
+---------------
+
+ -- Command: sendkey [`--num'|`--caps'|`--scroll'|`--insert'|
+ `--pause'|`--left-shift'|`--right-shift'|
+ `--sysrq'|`--numkey'|`--capskey'|`--scrollkey'|
+ `--insertkey'|`--left-alt'|`--right-alt'|
+ `--left-ctrl'|`--right-ctrl' `on'|`off']... [`no-led']
+ keystroke
+ Insert keystrokes into the keyboard buffer when booting.
+ Sometimes an operating system or chainloaded boot loader requires
+ particular keys to be pressed: for example, one might need to
+ press a particular key to enter "safe mode", or when chainloading
+ another boot loader one might send keystrokes to it to navigate
+ its menu.
+
+ You may provide up to 16 keystrokes (the length of the BIOS
+ keyboard buffer). Keystroke names may be upper-case or lower-case
+ letters, digits, or taken from the following table:
+
+ Name Key
+ ---------------------------------------------------------------
+ escape Escape
+ exclam !
+ at @
+ numbersign #
+ dollar $
+ percent %
+ caret ^
+ ampersand &
+ asterisk *
+ parenleft (
+ parenright )
+ minus -
+ underscore _
+ equal =
+ plus +
+ backspace Backspace
+ tab Tab
+ bracketleft [
+ braceleft {
+ bracketright ]
+ braceright }
+ enter Enter
+ control press and release Control
+ semicolon ;
+ colon :
+ quote '
+ doublequote "
+ backquote `
+ tilde ~
+ shift press and release left Shift
+ backslash \
+ bar |
+ comma ,
+ less <
+ period .
+ greater >
+ slash /
+ question ?
+ rshift press and release right Shift
+ alt press and release Alt
+ space space bar
+ capslock Caps Lock
+ F1 F1
+ F2 F2
+ F3 F3
+ F4 F4
+ F5 F5
+ F6 F6
+ F7 F7
+ F8 F8
+ F9 F9
+ F10 F10
+ F11 F11
+ F12 F12
+ num1 1 (numeric keypad)
+ num2 2 (numeric keypad)
+ num3 3 (numeric keypad)
+ num4 4 (numeric keypad)
+ num5 5 (numeric keypad)
+ num6 6 (numeric keypad)
+ num7 7 (numeric keypad)
+ num8 8 (numeric keypad)
+ num9 9 (numeric keypad)
+ num0 0 (numeric keypad)
+ numperiod . (numeric keypad)
+ numend End (numeric keypad)
+ numdown Down (numeric keypad)
+ numpgdown Page Down (numeric keypad)
+ numleft Left (numeric keypad)
+ numcenter 5 with Num Lock inactive (numeric
+ keypad)
+ numright Right (numeric keypad)
+ numhome Home (numeric keypad)
+ numup Up (numeric keypad)
+ numpgup Page Up (numeric keypad)
+ numinsert Insert (numeric keypad)
+ numdelete Delete (numeric keypad)
+ numasterisk * (numeric keypad)
+ numminus - (numeric keypad)
+ numplus + (numeric keypad)
+ numslash / (numeric keypad)
+ numenter Enter (numeric keypad)
+ delete Delete
+ insert Insert
+ home Home
+ end End
+ pgdown Page Down
+ pgup Page Up
+ down Down
+ up Up
+ left Left
+ right Right
+
+ As well as keystrokes, the `sendkey' command takes various options
+ that affect the BIOS keyboard status flags. These options take an
+ `on' or `off' parameter, specifying that the corresponding status
+ flag be set or unset; omitting the option for a given status flag
+ will leave that flag at its initial state at boot. The `--num',
+ `--caps', `--scroll', and `--insert' options emulate setting the
+ corresponding mode, while the `--numkey', `--capskey',
+ `--scrollkey', and `--insertkey' options emulate pressing and
+ holding the corresponding key. The other status flag options are
+ self-explanatory.
+
+ If the `--no-led' option is given, the status flag options will
+ have no effect on keyboard LEDs.
+
+ If the `sendkey' command is given multiple times, then only the
+ last invocation has any effect.
+
+ Since `sendkey' manipulates the BIOS keyboard buffer, it may cause
+ hangs, reboots, or other misbehaviour on some systems. If the
+ operating system or boot loader that runs after GRUB uses its own
+ keyboard driver rather than the BIOS keyboard functions, then
+ `sendkey' will have no effect.
+
+ This command is only available on PC BIOS systems.
+
+
+File: grub.info, Node: set, Next: true, Prev: sendkey, Up: Command-line and menu entry commands
+
+14.3.42 set
+-----------
+
+ -- Command: set [envvar=value]
+ Set the environment variable ENVVAR to VALUE. If invoked with no
+ arguments, print all environment variables with their values.
+
+
+File: grub.info, Node: true, Next: unset, Prev: set, Up: Command-line and menu entry commands
+
+14.3.43 true
+------------
+
+ -- Command: true
+ Do nothing, successfully. This is mainly useful in control
+ constructs such as `if' and `while' (*note Shell-like scripting::).
+
+
+File: grub.info, Node: unset, Next: uppermem, Prev: true, Up: Command-line and menu entry commands
+
+14.3.44 unset
+-------------
+
+ -- Command: unset envvar
+ Unset the environment variable ENVVAR.
+
+
+File: grub.info, Node: uppermem, Prev: unset, Up: Command-line and menu entry commands
+
+14.3.45 uppermem
+----------------
+
+This command is not yet implemented for GRUB 2, although it is planned.
+
+
+File: grub.info, Node: Security, Next: Supported kernels, Prev: Commands, Up: Top
+
+15 Authentication and authorisation
+***********************************
+
+By default, the boot loader interface is accessible to anyone with
+physical access to the console: anyone can select and edit any menu
+entry, and anyone can get direct access to a GRUB shell prompt. For
+most systems, this is reasonable since anyone with direct physical
+access has a variety of other ways to gain full access, and requiring
+authentication at the boot loader level would only serve to make it
+difficult to recover broken systems.
+
+ However, in some environments, such as kiosks, it may be appropriate
+to lock down the boot loader to require authentication before
+performing certain operations.
+
+ The `password' (*note password::) and `password_pbkdf2' (*note
+password_pbkdf2::) commands can be used to define users, each of which
+has an associated password. `password' sets the password in plain
+text, requiring `grub.cfg' to be secure; `password_pbkdf2' sets the
+password hashed using the Password-Based Key Derivation Function (RFC
+2898), requiring the use of `grub-mkpasswd-pbkdf2' (*note Invoking
+grub-mkpasswd-pbkdf2::) to generate password hashes.
+
+ In order to enable authentication support, the `superusers'
+environment variable must be set to a list of usernames, separated by
+any of spaces, commas, semicolons, pipes, or ampersands. Superusers
+are permitted to use the GRUB command line, edit menu entries, and
+execute any menu entry. If `superusers' is set, then use of the
+command line is automatically restricted to superusers.
+
+ Other users may be given access to specific menu entries by giving a
+list of usernames (as above) using the `--users' option to the
+`menuentry' command (*note menuentry::). If the `--users' option is
+not used for a menu entry, then that entry is unrestricted.
+
+ Putting this together, a typical `grub.cfg' fragment might look like
+this:
+
+ set superusers="root"
+ password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring
+ password user1 insecure
+
+ menuentry "May be run by any user" {
+ set root=(hd0,1)
+ linux /vmlinuz
+ }
+
+ menuentry "Superusers only" --users "" {
+ set root=(hd0,1)
+ linux /vmlinuz single
+ }
+
+ menuentry "May be run by user1 or a superuser" --users user1 {
+ set root=(hd0,2)
+ chainloader +1
+ }
+
+ The `grub-mkconfig' program does not yet have built-in support for
+generating configuration files with authentication. You can use
+`/etc/grub.d/40_custom' to add simple superuser authentication, by
+adding `set superusers=' and `password' or `password_pbkdf2' commands.
+
+
+File: grub.info, Node: Supported kernels, Next: Troubleshooting, Prev: Security, Up: Top
+
+16 Supported boot targets
+*************************
+
+X86 support is summarised in the following table. "Yes" means that the
+kernel works on the given platform, "crashes" means an early kernel
+crash which we hope will be fixed by concerned kernel developers. "no"
+means GRUB doesn't load the given kernel on a given platform.
+"headless" means that the kernel works but lacks console drivers (you
+can still use serial or network console). In case of "no" and
+"crashes" the reason is given in footnote.
+ BIOS Coreboot
+BIOS chainloading yes no (1)
+NTLDR yes no (1)
+FreeBSD bootloader yes crashes (1)
+32-bit kFreeBSD yes crashes (2,6)
+64-bit kFreeBSD yes crashes (2,6)
+32-bit kNetBSD yes crashes (1)
+64-bit kNetBSD yes crashes (2)
+32-bit kOpenBSD yes yes
+64-bit kOpenBSD yes yes
+Multiboot yes yes
+Multiboot2 yes yes
+32-bit Linux (legacy protocol) yes no (1)
+64-bit Linux (legacy protocol) yes no (1)
+32-bit Linux (modern protocol) yes yes
+64-bit Linux (modern protocol) yes yes
+32-bit XNU yes ?
+64-bit XNU yes ?
+32-bit EFI chainloader no (3) no (3)
+64-bit EFI chainloader no (3) no (3)
+Appleloader no (3) no (3)
+
+ Multiboot Qemu
+BIOS chainloading no (1) no (1)
+NTLDR no (1) no (1)
+FreeBSD bootloader crashes (1) crashes (1)
+32-bit kFreeBSD crashes (6) crashes (6)
+64-bit kFreeBSD crashes (6) crashes (6)
+32-bit kNetBSD crashes (1) crashes (1)
+64-bit kNetBSD yes yes
+32-bit kOpenBSD yes yes
+64-bit kOpenBSD yes yes
+Multiboot yes yes
+Multiboot2 yes yes
+32-bit Linux (legacy protocol) no (1) no (1)
+64-bit Linux (legacy protocol) no (1) no (1)
+32-bit Linux (modern protocol) yes yes
+64-bit Linux (modern protocol) yes yes
+32-bit XNU ? ?
+64-bit XNU ? ?
+32-bit EFI chainloader no (3) no (3)
+64-bit EFI chainloader no (3) no (3)
+Appleloader no (3) no (3)
+
+ 32-bit EFI 64-bit EFI
+BIOS chainloading no (1) no (1)
+NTLDR no (1) no (1)
+FreeBSD bootloader crashes (1) crashes (1)
+32-bit kFreeBSD headless headless
+64-bit kFreeBSD headless headless
+32-bit kNetBSD crashes (1) crashes (1)
+64-bit kNetBSD yes yes
+32-bit kOpenBSD headless headless
+64-bit kOpenBSD headless headless
+Multiboot yes yes
+Multiboot2 yes yes
+32-bit Linux (legacy protocol) no (1) no (1)
+64-bit Linux (legacy protocol) no (1) no (1)
+32-bit Linux (modern protocol) yes yes
+64-bit Linux (modern protocol) yes yes
+32-bit XNU yes yes
+64-bit XNU yes (5) yes
+32-bit EFI chainloader yes no (4)
+64-bit EFI chainloader no (4) yes
+Appleloader yes yes
+
+ IEEE1275
+BIOS chainloading no (1)
+NTLDR no (1)
+FreeBSD bootloader crashes (1)
+32-bit kFreeBSD crashes (6)
+64-bit kFreeBSD crashes (6)
+32-bit kNetBSD crashes (1)
+64-bit kNetBSD ?
+32-bit kOpenBSD ?
+64-bit kOpenBSD ?
+Multiboot ?
+Multiboot2 ?
+32-bit Linux (legacy protocol) no (1)
+64-bit Linux (legacy protocol) no (1)
+32-bit Linux (modern protocol) ?
+64-bit Linux (modern protocol) ?
+32-bit XNU ?
+64-bit XNU ?
+32-bit EFI chainloader no (3)
+64-bit EFI chainloader no (3)
+Appleloader no (3)
+
+ 1. Requires BIOS
+
+ 2. Crashes because the memory at 0x0-0x1000 isn't available
+
+ 3. EFI only
+
+ 4. 32-bit and 64-bit EFI have different structures and work in
+ different CPU modes so it's not possible to chainload 32-bit
+ bootloader on 64-bit platform and vice-versa
+
+ 5. Some modules may need to be disabled
+
+ 6. Requires ACPI
+
+ PowerPC and Sparc ports support only Linux. MIPS port supports Linux
+and multiboot2.
+
+17 Boot tests
+*************
+
+As you have seen in previous chapter the support matrix is pretty big
+and some of the configurations are only rarely used. To ensure the
+quality bootchecks are available for all x86 targets except EFI
+chainloader, Appleloader and XNU. All x86 platforms have bootcheck
+facility except ieee1275. Multiboot, multiboot2, BIOS chainloader,
+ntldr and freebsd-bootloader boot targets are tested only with a fake
+kernel images. Only Linux is tested among the payloads using Linux
+protocols.
+
+ Following variables must be defined:
+
+GRUB_PAYLOADS_DIR directory containing the required kernels
+GRUB_CBFSTOOL cbfstoll from Coreboot package (for coreboot
+ platform only)
+GRUB_COREBOOT_ROM empty Coreboot ROM
+GRUB_QEMU_OPTS additional options to be supplied to QEMU
+
+ Required files are:
+
+kfreebsd_env.i386 32-bit kFreeBSD device hints
+kfreebsd.i386 32-bit FreeBSD kernel image
+kfreebsd.x86_64, same from 64-bit kFreeBSD
+kfreebsd_env.x86_64
+knetbsd.i386 32-bit NetBSD kernel image
+knetbsd.miniroot.i386 32-bit kNetBSD miniroot.kmod.
+knetbsd.x86_64, same from 64-bit kNetBSD
+knetbsd.miniroot.x86_64
+kopenbsd.i386 32-bit OpenBSD kernel bsd.rd image
+kopenbsd.x86_64 same from 64-bit kOpenBSD
+linux.i386 32-bit Linux
+linux.x86_64 64-bit Linux
+
+
+File: grub.info, Node: Troubleshooting, Next: Invoking grub-install, Prev: Supported kernels, Up: Top
+
+18 Error messages produced by GRUB
+**********************************
+
+* Menu:
+
+* GRUB only offers a rescue shell::
+
+
+File: grub.info, Node: GRUB only offers a rescue shell, Up: Troubleshooting
+
+18.1 GRUB only offers a rescue shell
+====================================
+
+GRUB's normal start-up procedure involves setting the `prefix'
+environment variable to a value set in the core image by
+`grub-install', setting the `root' variable to match, loading the
+`normal' module from the prefix, and running the `normal' command
+(*note normal::). This command is responsible for reading
+`/boot/grub/grub.cfg', running the menu, and doing all the useful
+things GRUB is supposed to do.
+
+ If, instead, you only get a rescue shell, this usually means that
+GRUB failed to load the `normal' module for some reason. It may be
+possible to work around this temporarily: for instance, if the reason
+for the failure is that `prefix' is wrong (perhaps it refers to the
+wrong device, or perhaps the path to `/boot/grub' was not correctly
+made relative to the device), then you can correct this and enter
+normal mode manually:
+
+ # Inspect the current prefix (and other preset variables):
+ set
+ # Find out which devices are available:
+ ls
+ # Set to the correct value, which might be something like this:
+ set prefix=(hd0,1)/grub
+ set root=(hd0,1)
+ insmod normal
+ normal
+
+ However, any problem that leaves you in the rescue shell probably
+means that GRUB was not correctly installed. It may be more useful to
+try to reinstall it properly using `grub-install DEVICE' (*note
+Invoking grub-install::). When doing this, there are a few things to
+remember:
+
+ * Drive ordering in your operating system may not be the same as the
+ boot drive ordering used by your firmware. Do not assume that
+ your first hard drive (e.g. `/dev/sda') is the one that your
+ firmware will boot from. `device.map' (*note Device map::) can be
+ used to override this, but it is usually better to use UUIDs or
+ file system labels and avoid depending on drive ordering entirely.
+
+ * At least on BIOS systems, if you tell `grub-install' to install
+ GRUB to a partition but GRUB has already been installed in the
+ master boot record, then the GRUB installation in the partition
+ will be ignored.
+
+ * If possible, it is generally best to avoid installing GRUB to a
+ partition (unless it is a special partition for the use of GRUB
+ alone, such as the BIOS Boot Partition used on GPT). Doing this
+ means that GRUB may stop being able to read its core image due to
+ a file system moving blocks around, such as while defragmenting,
+ running checks, or even during normal operation. Installing to
+ the whole disk device is normally more robust.
+
+ * Check that GRUB actually knows how to read from the device and
+ file system containing `/boot/grub'. It will not be able to read
+ from encrypted devices, nor from file systems for which support
+ has not yet been added to GRUB.
+
+
+File: grub.info, Node: Invoking grub-install, Next: Invoking grub-mkconfig, Prev: Troubleshooting, Up: Top
+
+19 Invoking grub-install
+************************
+
+The program `grub-install' installs GRUB on your drive using
+`grub-mkimage' and (on some platforms) `grub-setup'. You must specify
+the device name on which you want to install GRUB, like this:
+
+ grub-install INSTALL_DEVICE
+
+ The device name INSTALL_DEVICE is an OS device name or a GRUB device
+name.
+
+ `grub-install' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version number of GRUB and exit.
+
+`--boot-directory=DIR'
+ Install GRUB images under the directory `DIR/grub/' This option is
+ useful when you want to install GRUB into a separate partition or
+ a removable disk. If this option is not specified then it
+ defaults to `/boot', so
+
+ grub-install /dev/sda
+
+ is equivalent to
+
+ grub-install --boot-directory=/boot/ /dev/sda
+
+ Here is an example in which you have a separate "boot" partition
+ which is mounted on `/mnt/boot':
+
+ grub-install --boot-directory=/mnt/boot /dev/sdb
+
+`--recheck'
+ Recheck the device map, even if `/boot/grub/device.map' already
+ exists. You should use this option whenever you add/remove a disk
+ into/from your computer.
+
+
+File: grub.info, Node: Invoking grub-mkconfig, Next: Invoking grub-mkpasswd-pbkdf2, Prev: Invoking grub-install, Up: Top
+
+20 Invoking grub-mkconfig
+*************************
+
+The program `grub-mkconfig' generates a configuration file for GRUB
+(*note Simple configuration::).
+
+ grub-mkconfig -o /boot/grub/grub.cfg
+
+ `grub-mkconfig' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version number of GRUB and exit.
+
+`-o FILE'
+`--output=FILE'
+ Send the generated configuration file to FILE. The default is to
+ send it to standard output.
+
+
+File: grub.info, Node: Invoking grub-mkpasswd-pbkdf2, Next: Invoking grub-mkrescue, Prev: Invoking grub-mkconfig, Up: Top
+
+21 Invoking grub-mkpasswd-pbkdf2
+********************************
+
+The program `grub-mkpasswd-pbkdf2' generates password hashes for GRUB
+(*note Security::).
+
+ grub-mkpasswd-pbkdf2
+
+ `grub-mkpasswd-pbkdf2' accepts the following options:
+
+`-c NUMBER'
+`--iteration-count=NUMBER'
+ Number of iterations of the underlying pseudo-random function.
+ Defaults to 10000.
+
+`-l NUMBER'
+`--buflen=NUMBER'
+ Length of the generated hash. Defaults to 64.
+
+`-s NUMBER'
+`--salt=NUMBER'
+ Length of the salt. Defaults to 64.
+
+
+File: grub.info, Node: Invoking grub-mkrescue, Next: Obtaining and Building GRUB, Prev: Invoking grub-mkpasswd-pbkdf2, Up: Top
+
+22 Invoking grub-mkrescue
+*************************
+
+The program `grub-mkrescue' generates a bootable GRUB rescue image
+(*note Making a GRUB bootable CD-ROM::).
+
+ grub-mkrescue -o grub.iso
+
+ All arguments not explicitly listed as `grub-mkrescue' options are
+passed on directly to `xorriso' in `mkisofs' emulation mode. Options
+passed to `xorriso' will normally be interpreted as `mkisofs' options;
+if the option `--' is used, then anything after that will be
+interpreted as native `xorriso' options.
+
+ Non-option arguments specify additional source directories. This is
+commonly used to add extra files to the image:
+
+ mkdir -p disk/boot/grub
+ (add extra files to `disk/boot/grub')
+ grub-mkrescue -o grub.iso disk
+
+ `grub-mkrescue' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version number of GRUB and exit.
+
+`-o FILE'
+`--output=FILE'
+ Save output in FILE. This "option" is required.
+
+`--modules=MODULES'
+ Pre-load the named GRUB modules in the image. Multiple entries in
+ MODULES should be separated by whitespace (so you will probably
+ need to quote this for your shell).
+
+`--rom-directory=DIR'
+ If generating images for the QEMU or Coreboot platforms, copy the
+ resulting `qemu.img' or `coreboot.elf' files respectively to the
+ DIR directory as well as including them in the image.
+
+`--xorriso=FILE'
+ Use FILE as the `xorriso' program, rather than the built-in
+ default.
+
+`--grub-mkimage=FILE'
+ Use FILE as the `grub-mkimage' program, rather than the built-in
+ default.
+
+
+File: grub.info, Node: Obtaining and Building GRUB, Next: Reporting bugs, Prev: Invoking grub-mkrescue, Up: Top
+
+Appendix A How to obtain and build GRUB
+***************************************
+
+ *Caution:* GRUB requires binutils-2.9.1.0.23 or later because the
+ GNU assembler has been changed so that it can produce real 16bits
+ machine code between 2.9.1 and 2.9.1.0.x. See
+ `http://sources.redhat.com/binutils/', to obtain information on
+ how to get the latest version.
+
+ GRUB is available from the GNU alpha archive site
+`ftp://alpha.gnu.org/gnu/grub' or any of its mirrors. The file will be
+named grub-version.tar.gz. The current version is 1.99, so the file you
+should grab is:
+
+ `ftp://alpha.gnu.org/gnu/grub/grub-1.99.tar.gz'
+
+ To unbundle GRUB use the instruction:
+
+ zcat grub-1.99.tar.gz | tar xvf -
+
+ which will create a directory called `grub-1.99' with all the
+sources. You can look at the file `INSTALL' for detailed instructions
+on how to build and install GRUB, but you should be able to just do:
+
+ cd grub-1.99
+ ./configure
+ make install
+
+ Also, the latest version is available using Bazaar. See
+`http://www.gnu.org/software/grub/grub-download.en.html' for more
+information.
+
+
+File: grub.info, Node: Reporting bugs, Next: Future, Prev: Obtaining and Building GRUB, Up: Top
+
+Appendix B Reporting bugs
+*************************
+
+These are the guideline for how to report bugs. Take a look at this
+list below before you submit bugs:
+
+ 1. Before getting unsettled, read this manual through and through.
+ Also, see the GNU GRUB FAQ
+ (http://www.gnu.org/software/grub/grub-faq.html).
+
+ 2. Always mention the information on your GRUB. The version number
+ and the configuration are quite important. If you build it
+ yourself, write the options specified to the configure script and
+ your operating system, including the versions of gcc and binutils.
+
+ 3. If you have trouble with the installation, inform us of how you
+ installed GRUB. Don't omit error messages, if any. Just `GRUB hangs
+ up when it boots' is not enough.
+
+ The information on your hardware is also essential. These are
+ especially important: the geometries and the partition tables of
+ your hard disk drives and your BIOS.
+
+ 4. If GRUB cannot boot your operating system, write down _everything_
+ you see on the screen. Don't paraphrase them, like `The foo OS
+ crashes with GRUB, even though it can boot with the bar boot
+ loader just fine'. Mention the commands you executed, the messages
+ printed by them, and information on your operating system
+ including the version number.
+
+ 5. Explain what you wanted to do. It is very useful to know your
+ purpose and your wish, and how GRUB didn't satisfy you.
+
+ 6. If you can investigate the problem yourself, please do. That will
+ give you and us much more information on the problem. Attaching a
+ patch is even better.
+
+ When you attach a patch, make the patch in unified diff format, and
+ write ChangeLog entries. But, even when you make a patch, don't
+ forget to explain the problem, so that we can understand what your
+ patch is for.
+
+ 7. Write down anything that you think might be related. Please
+ understand that we often need to reproduce the same problem you
+ encountered in our environment. So your information should be
+ sufficient for us to do the same thing--Don't forget that we
+ cannot see your computer directly. If you are not sure whether to
+ state a fact or leave it out, state it! Reporting too many things
+ is much better than omitting something important.
+
+ If you follow the guideline above, submit a report to the Bug
+Tracking System (http://savannah.gnu.org/bugs/?group=grub).
+Alternatively, you can submit a report via electronic mail to
+<bug-grub@gnu.org>, but we strongly recommend that you use the Bug
+Tracking System, because e-mail can be passed over easily.
+
+ Once we get your report, we will try to fix the bugs.
+
+
+File: grub.info, Node: Future, Next: Copying This Manual, Prev: Reporting bugs, Up: Top
+
+Appendix C Where GRUB will go
+*****************************
+
+GRUB 2 is now quite stable and used in many production systems. We are
+currently working towards a 2.0 release.
+
+ If you are interested in the development of GRUB 2, take a look at
+the homepage (http://www.gnu.org/software/grub/grub.html).
+
+
+File: grub.info, Node: Copying This Manual, Next: Index, Prev: Future, Up: Top
+
+Appendix D Copying This Manual
+******************************
+
+* Menu:
+
+* GNU Free Documentation License:: License for copying this manual.
+
+
+File: grub.info, Node: GNU Free Documentation License, Up: Copying This Manual
+
+D.1 GNU Free Documentation License
+==================================
+
+ Version 1.2, November 2002
+
+ Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book.
+ We recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it
+ can be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You
+ accept the license if you copy, modify or distribute the work in a
+ way requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in
+ the notice that says that the Document is released under this
+ License. If a section does not fit the above definition of
+ Secondary then it is not allowed to be designated as Invariant.
+ The Document may contain zero Invariant Sections. If the Document
+ does not identify any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images
+ composed of pixels) generic paint programs or (for drawings) some
+ widely available drawing editor, and that is suitable for input to
+ text formatters or for automatic translation to a variety of
+ formats suitable for input to text formatters. A copy made in an
+ otherwise Transparent file format whose markup, or absence of
+ markup, has been arranged to thwart or discourage subsequent
+ modification by readers is not Transparent. An image format is
+ not Transparent if used for any substantial amount of text. A
+ copy that is not "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and
+ standard-conforming simple HTML, PostScript or PDF designed for
+ human modification. Examples of transparent image formats include
+ PNG, XCF and JPG. Opaque formats include proprietary formats that
+ can be read and edited only by proprietary word processors, SGML or
+ XML for which the DTD and/or processing tools are not generally
+ available, and the machine-generated HTML, PostScript or PDF
+ produced by some word processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow
+ the conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the
+ title equally prominent and visible. You may add other material
+ on the covers in addition. Copying with changes limited to the
+ covers, as long as they preserve the title of the Document and
+ satisfy these conditions, can be treated as verbatim copying in
+ other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a
+ machine-readable Transparent copy along with each Opaque copy, or
+ state in or with each Opaque copy a computer-network location from
+ which the general network-using public has access to download
+ using public-standard network protocols a complete Transparent
+ copy of the Document, free of added material. If you use the
+ latter option, you must take reasonably prudent steps, when you
+ begin distribution of Opaque copies in quantity, to ensure that
+ this Transparent copy will remain thus accessible at the stated
+ location until at least one year after the last time you
+ distribute an Opaque copy (directly or through your agents or
+ retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of
+ copies, to give them a chance to provide you with an updated
+ version of the Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with
+ the Modified Version filling the role of the Document, thus
+ licensing distribution and modification of the Modified Version to
+ whoever possesses a copy of it. In addition, you must do these
+ things in the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of
+ previous versions (which should, if there were any, be listed
+ in the History section of the Document). You may use the
+ same title as a previous version if the original publisher of
+ that version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on
+ the Title Page. If there is no section Entitled "History" in
+ the Document, create one stating the title, year, authors,
+ and publisher of the Document as given on its Title Page,
+ then add an item describing the Modified Version as stated in
+ the previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in
+ the "History" section. You may omit a network location for a
+ work that was published at least four years before the
+ Document itself, or if the original publisher of the version
+ it refers to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the
+ section all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section
+ titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option
+ designate some or all of these sections as invariant. To do this,
+ add their titles to the list of Invariant Sections in the Modified
+ Version's license notice. These titles must be distinct from any
+ other section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end
+ of the list of Cover Texts in the Modified Version. Only one
+ passage of Front-Cover Text and one of Back-Cover Text may be
+ added by (or through arrangements made by) any one entity. If the
+ Document already includes a cover text for the same cover,
+ previously added by you or by arrangement made by the same entity
+ you are acting on behalf of, you may not add another; but you may
+ replace the old one, on explicit permission from the previous
+ publisher that added the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination
+ all of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the
+ documents in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow
+ this License in all other respects regarding verbatim copying of
+ that document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of
+ a storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided for under this License. Any other
+ attempt to copy, modify, sublicense or distribute the Document is
+ void, and will automatically terminate your rights under this
+ License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses
+ terminated so long as such parties remain in full compliance.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ `http://www.gnu.org/copyleft/'.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If
+ the Document does not specify a version number of this License,
+ you may choose any version ever published (not as a draft) by the
+ Free Software Foundation.
+
+D.1.1 ADDENDUM: How to use this License for your documents
+----------------------------------------------------------
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.2
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License, to
+permit their use in free software.
+
+
+File: grub.info, Node: Index, Prev: Copying This Manual, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* acpi: acpi. (line 11)
+* badram: badram. (line 7)
+* blocklist: blocklist. (line 7)
+* boot: boot. (line 7)
+* cat: cat. (line 7)
+* chainloader: chainloader. (line 7)
+* cmp: cmp. (line 7)
+* configfile: configfile. (line 7)
+* cpuid: cpuid. (line 7)
+* crc: crc. (line 7)
+* date: date. (line 7)
+* drivemap: drivemap. (line 7)
+* echo: echo. (line 7)
+* export: export. (line 7)
+* false: false. (line 7)
+* FDL, GNU Free Documentation License: GNU Free Documentation License.
+ (line 6)
+* gettext: gettext. (line 7)
+* gptsync: gptsync. (line 7)
+* halt: halt. (line 7)
+* help: help. (line 7)
+* initrd: initrd. (line 7)
+* initrd16: initrd16. (line 7)
+* insmod: insmod. (line 7)
+* keystatus: keystatus. (line 7)
+* linux: linux. (line 7)
+* linux16: linux16. (line 7)
+* list_env: list_env. (line 7)
+* load_env: load_env. (line 7)
+* loopback: loopback. (line 7)
+* ls: ls. (line 7)
+* menuentry: menuentry. (line 8)
+* normal: normal. (line 7)
+* normal_exit: normal_exit. (line 7)
+* parttool: parttool. (line 7)
+* password: password. (line 7)
+* password_pbkdf2: password_pbkdf2. (line 7)
+* play: play. (line 7)
+* pxe_unload: pxe_unload. (line 7)
+* read: read. (line 7)
+* reboot: reboot. (line 7)
+* save_env: save_env. (line 7)
+* search: search. (line 8)
+* sendkey: sendkey. (line 12)
+* serial: serial. (line 8)
+* set: set. (line 7)
+* submenu: submenu. (line 8)
+* terminal_input: terminal_input. (line 8)
+* terminal_output: terminal_output. (line 8)
+* terminfo: terminfo. (line 7)
+* true: true. (line 7)
+* unset: unset. (line 7)
+
+
+
+Tag Table:
+Node: Top961
+Node: Introduction3282
+Node: Overview3726
+Node: Overview-Footnotes5710
+Ref: Overview-Footnote-15771
+Node: History5932
+Node: Changes from GRUB Legacy8020
+Node: Features10496
+Node: Features-Footnotes16487
+Ref: Features-Footnote-116548
+Ref: Features-Footnote-216694
+Node: Role of a boot loader16839
+Node: Role of a boot loader-Footnotes18177
+Ref: Role of a boot loader-Footnote-118264
+Node: Naming convention18343
+Node: Installation21218
+Node: Installing GRUB using grub-install22321
+Node: Making a GRUB bootable CD-ROM24492
+Node: Making a GRUB bootable CD-ROM-Footnotes26346
+Ref: Making a GRUB bootable CD-ROM-Footnote-126449
+Node: Device map26524
+Node: BIOS installation28701
+Node: Booting32078
+Node: General boot methods32470
+Node: Loading an operating system directly33211
+Node: Chain-loading33942
+Node: OS-specific notes34913
+Node: GNU/Hurd35195
+Node: GNU/Linux36312
+Node: DOS/Windows37935
+Node: Configuration39708
+Node: Simple configuration40250
+Node: Shell-like scripting49686
+Node: Shell-like scripting-Footnotes57596
+Ref: Shell-like scripting-Footnote-157681
+Node: Embedded configuration57808
+Node: Theme file format60641
+Ref: Pixmap-styled progress bar62064
+Ref: Plain progress bar62076
+Ref: An example of the slices (in red) used for a terminal window. This drawing was created and sliced in Inkscape_65505
+Node: Network79727
+Node: Serial terminal82130
+Node: Vendor power-on keys84357
+Node: Images86187
+Node: Filesystem91147
+Node: Device syntax91834
+Node: File name syntax93326
+Node: Block list syntax94080
+Node: Interface94813
+Node: Command-line interface95635
+Node: Command-line interface-Footnotes97576
+Ref: Command-line interface-Footnote-197665
+Node: Menu interface97760
+Node: Menu entry editor98770
+Node: Environment99508
+Node: Special environment variables100212
+Node: biosnum100963
+Node: chosen101477
+Node: color_highlight101919
+Node: color_normal102325
+Node: debug102947
+Node: default103294
+Node: fallback104221
+Node: gfxmode104552
+Node: gfxpayload105285
+Node: gfxterm_font106437
+Node: icondir106736
+Node: lang107052
+Node: locale_dir107521
+Node: menu_color_highlight108030
+Node: menu_color_normal108526
+Node: net_pxe_boot_file109019
+Node: net_pxe_dhcp_server_name109230
+Node: net_pxe_domain109452
+Node: net_pxe_extensionspath109659
+Node: net_pxe_hostname109874
+Node: net_pxe_ip110073
+Node: net_pxe_mac110249
+Node: net_pxe_rootpath110427
+Node: pager110610
+Node: prefix110864
+Node: pxe_blksize111313
+Node: pxe_default_gateway111490
+Node: pxe_default_server111695
+Node: root111891
+Node: superusers112432
+Node: theme112680
+Node: timeout113001
+Node: Environment block113498
+Node: Commands114930
+Node: Menu-specific commands115763
+Node: menuentry116490
+Node: submenu117497
+Node: General commands118005
+Node: serial118501
+Node: terminal_input119546
+Node: terminal_output120212
+Node: terminfo120879
+Node: Command-line and menu entry commands122014
+Node: acpi124985
+Node: badram126024
+Node: blocklist127066
+Node: boot127300
+Node: cat127621
+Node: chainloader128256
+Node: cmp128878
+Node: configfile129429
+Node: cpuid129729
+Node: crc130194
+Node: date130384
+Node: drivemap130923
+Node: echo131726
+Node: export132663
+Node: false132973
+Node: gettext133269
+Node: gptsync133716
+Node: halt134661
+Node: help134987
+Node: initrd135450
+Node: initrd16135862
+Node: insmod136367
+Node: keystatus136589
+Node: linux137227
+Node: linux16138130
+Node: list_env138844
+Node: load_env139198
+Node: loopback139576
+Node: ls140024
+Node: normal140569
+Node: normal_exit141328
+Node: parttool141650
+Node: password143155
+Node: password_pbkdf2143437
+Node: play143845
+Node: pxe_unload144597
+Node: read144876
+Node: reboot145225
+Node: save_env145410
+Node: search145796
+Node: sendkey146574
+Node: set152848
+Node: true153146
+Node: unset153431
+Node: uppermem153637
+Node: Security153838
+Node: Supported kernels156526
+Node: Troubleshooting164014
+Node: GRUB only offers a rescue shell164240
+Node: Invoking grub-install167166
+Node: Invoking grub-mkconfig168544
+Node: Invoking grub-mkpasswd-pbkdf2169181
+Node: Invoking grub-mkrescue169839
+Node: Obtaining and Building GRUB171602
+Node: Reporting bugs172846
+Node: Future175649
+Node: Copying This Manual176049
+Node: GNU Free Documentation License176277
+Node: Index198685
+
+End Tag Table
diff --git a/docs/grub.texi b/docs/grub.texi
new file mode 100644
index 0000000..b11e383
--- /dev/null
+++ b/docs/grub.texi
@@ -0,0 +1,4455 @@
+\input texinfo
+@c -*-texinfo-*-
+@c %**start of header
+@setfilename grub.info
+@include version.texi
+@settitle GNU GRUB Manual @value{VERSION}
+@c Unify all our little indices for now.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+@c %**end of header
+
+@footnotestyle separate
+@paragraphindent 3
+@finalout
+
+@copying
+This manual is for GNU GRUB (version @value{VERSION},
+@value{UPDATED}).
+
+Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010 Free Software Foundation, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections.
+@end quotation
+@end copying
+
+@dircategory Kernel
+@direntry
+* GRUB: (grub). The GRand Unified Bootloader
+* grub-install: (grub)Invoking grub-install. Install GRUB on your drive
+* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration
+* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2.
+* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image
+@end direntry
+
+@setchapternewpage odd
+
+@titlepage
+@sp 10
+@title the GNU GRUB manual
+@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
+@author Gordon Matzigkeit
+@author Yoshinori K. Okuji
+@author Colin Watson
+@author Colin D. Bennett
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@c Output the table of contents at the beginning.
+@contents
+
+@finalout
+@headings double
+
+@ifnottex
+@node Top
+@top GNU GRUB manual
+
+This is the documentation of GNU GRUB, the GRand Unified Bootloader,
+a flexible and powerful boot loader program for a wide range of
+architectures.
+
+This edition documents version @value{VERSION}.
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Introduction:: Capturing the spirit of GRUB
+* Naming convention:: Names of your drives in GRUB
+* Installation:: Installing GRUB on your drive
+* Booting:: How to boot different operating systems
+* Configuration:: Writing your own configuration file
+* Theme file format:: Format of GRUB theme files
+* Network:: Downloading OS images from a network
+* Serial terminal:: Using GRUB via a serial line
+* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys
+* Images:: GRUB image files
+* Filesystem:: Filesystem syntax and semantics
+* Interface:: The menu and the command-line
+* Environment:: GRUB environment variables
+* Commands:: The list of available builtin commands
+* Security:: Authentication and authorisation
+* Supported kernels:: The list of supported kernels
+* Troubleshooting:: Error messages produced by GRUB
+* Invoking grub-install:: How to use the GRUB installer
+* Invoking grub-mkconfig:: Generate a GRUB configuration file
+* Invoking grub-mkpasswd-pbkdf2::
+ Generate GRUB password hashes
+* Invoking grub-mkrescue:: Make a GRUB rescue image
+* Obtaining and Building GRUB:: How to obtain and build GRUB
+* Reporting bugs:: Where you should send a bug report
+* Future:: Some future plans on GRUB
+* Copying This Manual:: Copying This Manual
+* Index::
+@end menu
+
+
+@node Introduction
+@chapter Introduction to GRUB
+
+@menu
+* Overview:: What exactly GRUB is and how to use it
+* History:: From maggot to house fly
+* Changes from GRUB Legacy:: Differences from previous versions
+* Features:: GRUB features
+* Role of a boot loader:: The role of a boot loader
+@end menu
+
+
+@node Overview
+@section Overview
+
+Briefly, a @dfn{boot loader} is the first software program that runs when
+a computer starts. It is responsible for loading and transferring
+control to an operating system @dfn{kernel} software (such as Linux or
+GNU Mach). The kernel, in turn, initializes the rest of the operating
+system (e.g. a GNU system).
+
+GNU GRUB is a very powerful boot loader, which can load a wide variety
+of free operating systems, as well as proprietary operating systems with
+chain-loading@footnote{@dfn{chain-load} is the mechanism for loading
+unsupported operating systems by loading another boot loader. It is
+typically used for loading DOS or Windows.}. GRUB is designed to
+address the complexity of booting a personal computer; both the
+program and this manual are tightly bound to that computer platform,
+although porting to other platforms may be addressed in the future.
+
+One of the important features in GRUB is flexibility; GRUB understands
+filesystems and kernel executable formats, so you can load an arbitrary
+operating system the way you like, without recording the physical
+position of your kernel on the disk. Thus you can load the kernel
+just by specifying its file name and the drive and partition where the
+kernel resides.
+
+When booting with GRUB, you can use either a command-line interface
+(@pxref{Command-line interface}), or a menu interface (@pxref{Menu
+interface}). Using the command-line interface, you type the drive
+specification and file name of the kernel manually. In the menu
+interface, you just select an OS using the arrow keys. The menu is
+based on a configuration file which you prepare beforehand
+(@pxref{Configuration}). While in the menu, you can switch to the
+command-line mode, and vice-versa. You can even edit menu entries
+before using them.
+
+In the following chapters, you will learn how to specify a drive, a
+partition, and a file name (@pxref{Naming convention}) to GRUB, how to
+install GRUB on your drive (@pxref{Installation}), and how to boot your
+OSes (@pxref{Booting}), step by step.
+
+
+@node History
+@section History of GRUB
+
+GRUB originated in 1995 when Erich Boleyn was trying to boot the GNU
+Hurd with the University of Utah's Mach 4 microkernel (now known as GNU
+Mach). Erich and Brian Ford designed the Multiboot Specification
+(@pxref{Top, Multiboot Specification, Motivation, multiboot, The Multiboot
+Specification}), because they were determined not to add to the large
+number of mutually-incompatible PC boot methods.
+
+Erich then began modifying the FreeBSD boot loader so that it would
+understand Multiboot. He soon realized that it would be a lot easier
+to write his own boot loader from scratch than to keep working on the
+FreeBSD boot loader, and so GRUB was born.
+
+Erich added many features to GRUB, but other priorities prevented him
+from keeping up with the demands of its quickly-expanding user base. In
+1999, Gordon Matzigkeit and Yoshinori K. Okuji adopted GRUB as an
+official GNU package, and opened its development by making the latest
+sources available via anonymous CVS. @xref{Obtaining and Building
+GRUB}, for more information.
+
+Over the next few years, GRUB was extended to meet many needs, but it
+quickly became clear that its design was not keeping up with the extensions
+being made to it, and we reached the point where it was very difficult to
+make any further changes without breaking existing features. Around 2002,
+Yoshinori K. Okuji started work on PUPA (Preliminary Universal Programming
+Architecture for GNU GRUB), aiming to rewrite the core of GRUB to make it
+cleaner, safer, more robust, and more powerful. PUPA was eventually renamed
+to GRUB 2, and the original version of GRUB was renamed to GRUB Legacy.
+Small amounts of maintenance continued to be done on GRUB Legacy, but the
+last release (0.97) was made in 2005 and at the time of writing it seems
+unlikely that there will be another.
+
+By around 2007, GNU/Linux distributions started to use GRUB 2 to limited
+extents, and by the end of 2009 multiple major distributions were installing
+it by default.
+
+
+@node Changes from GRUB Legacy
+@section Differences from previous versions
+
+GRUB 2 is a rewrite of GRUB (@pxref{History}), although it shares many
+characteristics with the previous version, now known as GRUB Legacy. Users
+of GRUB Legacy may need some guidance to find their way around this new
+version.
+
+@itemize @bullet
+@item
+The configuration file has a new name (@file{grub.cfg} rather than
+@file{menu.lst} or @file{grub.conf}), new syntax (@pxref{Configuration}) and
+many new commands (@pxref{Commands}). Configuration cannot be copied over
+directly, although most GRUB Legacy users should not find the syntax too
+surprising.
+
+@item
+@file{grub.cfg} is typically automatically generated by
+@command{grub-mkconfig} (@pxref{Simple configuration}). This makes it
+easier to handle versioned kernel upgrades.
+
+@item
+Partition numbers in GRUB device names now start at 1, not 0 (@pxref{Naming
+convention}).
+
+@item
+The configuration file is now written in something closer to a full
+scripting language: variables, conditionals, and loops are available.
+
+@item
+A small amount of persistent storage is available across reboots, using the
+@command{save_env} and @command{load_env} commands in GRUB and the
+@command{grub-editenv} utility. This is not available in all configurations
+(@pxref{Environment block}).
+
+@item
+GRUB 2 has more reliable ways to find its own files and those of target
+kernels on multiple-disk systems, and has commands (@pxref{search}) to find
+devices using file system labels or Universally Unique Identifiers (UUIDs).
+
+@item
+GRUB 2 is available for several other types of system in addition to the PC
+BIOS systems supported by GRUB Legacy: PC EFI, PC coreboot, PowerPC, SPARC,
+and MIPS Lemote Yeeloong are all supported.
+
+@item
+Many more file systems are supported, including but not limited to ext4,
+HFS+, and NTFS.
+
+@item
+GRUB 2 can read files directly from LVM and RAID devices.
+
+@item
+A graphical terminal and a graphical menu system are available.
+
+@item
+GRUB 2's interface can be translated, including menu entry names.
+
+@item
+The image files (@pxref{Images}) that make up GRUB have been reorganised;
+Stage 1, Stage 1.5, and Stage 2 are no more.
+
+@item
+GRUB 2 puts many facilities in dynamically loaded modules, allowing the core
+image to be smaller, and allowing the core image to be built in more
+flexible ways.
+@end itemize
+
+
+@node Features
+@section GRUB features
+
+The primary requirement for GRUB is that it be compliant with the
+@dfn{Multiboot Specification}, which is described in @ref{Top, Multiboot
+Specification, Motivation, multiboot, The Multiboot Specification}.
+
+The other goals, listed in approximate order of importance, are:
+
+@itemize @bullet{}
+@item
+Basic functions must be straightforward for end-users.
+
+@item
+Rich functionality to support kernel experts and designers.
+
+@item
+Backward compatibility for booting FreeBSD, NetBSD, OpenBSD, and
+Linux. Proprietary kernels (such as DOS, Windows NT, and OS/2) are
+supported via a chain-loading function.
+@end itemize
+
+Except for specific compatibility modes (chain-loading and the Linux
+@dfn{piggyback} format), all kernels will be started in much the same
+state as in the Multiboot Specification. Only kernels loaded at 1 megabyte
+or above are presently supported. Any attempt to load below that
+boundary will simply result in immediate failure and an error message
+reporting the problem.
+
+In addition to the requirements above, GRUB has the following features
+(note that the Multiboot Specification doesn't require all the features
+that GRUB supports):
+
+@table @asis
+@item Recognize multiple executable formats
+Support many of the @dfn{a.out} variants plus @dfn{ELF}. Symbol
+tables are also loaded.
+
+@item Support non-Multiboot kernels
+Support many of the various free 32-bit kernels that lack Multiboot
+compliance (primarily FreeBSD, NetBSD, OpenBSD, and
+Linux). Chain-loading of other boot loaders is also supported.
+
+@item Load multiples modules
+Fully support the Multiboot feature of loading multiple modules.
+
+@item Load a configuration file
+Support a human-readable text configuration file with preset boot
+commands. You can also load another configuration file dynamically and
+embed a preset configuration file in a GRUB image file. The list of
+commands (@pxref{Commands}) are a superset of those supported on the
+command-line. An example configuration file is provided in
+@ref{Configuration}.
+
+@item Provide a menu interface
+A menu interface listing preset boot commands, with a programmable
+timeout, is available. There is no fixed limit on the number of boot
+entries, and the current implementation has space for several hundred.
+
+@item Have a flexible command-line interface
+A fairly flexible command-line interface, accessible from the menu,
+is available to edit any preset commands, or write a new boot command
+set from scratch. If no configuration file is present, GRUB drops to
+the command-line.
+
+The list of commands (@pxref{Commands}) are a subset of those supported
+for configuration files. Editing commands closely resembles the Bash
+command-line (@pxref{Command Line Editing, Bash, Command Line Editing,
+features, Bash Features}), with @key{TAB}-completion of commands,
+devices, partitions, and files in a directory depending on context.
+
+@item Support multiple filesystem types
+Support multiple filesystem types transparently, plus a useful explicit
+blocklist notation. The currently supported filesystem types are @dfn{Amiga
+Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS}, @dfn{cpio}, @dfn{Linux
+ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{HFS}, @dfn{HFS+},
+@dfn{ISO9660}, @dfn{JFS}, @dfn{Minix fs}, @dfn{nilfs2}, @dfn{NTFS},
+@dfn{ReiserFS}, @dfn{Amiga Smart FileSystem (SFS)}, @dfn{tar}, @dfn{UDF},
+@dfn{BSD UFS/UFS2}, and @dfn{XFS}. @xref{Filesystem}, for more information.
+
+@item Support automatic decompression
+Can decompress files which were compressed by @command{gzip} or
+@command{xz}@footnote{Only CRC32 data integrity check is supported (xz default
+is CRC64 so one should use --check=crc32 option). LZMA BCJ filters are
+supported.}. This function is both automatic and transparent to the user
+(i.e. all functions operate upon the uncompressed contents of the specified
+files). This greatly reduces a file size and loading time, a
+particularly great benefit for floppies.@footnote{There are a few
+pathological cases where loading a very badly organized ELF kernel might
+take longer, but in practice this never happen.}
+
+It is conceivable that some kernel modules should be loaded in a
+compressed state, so a different module-loading command can be specified
+to avoid uncompressing the modules.
+
+@item Access data on any installed device
+Support reading data from any or all floppies or hard disk(s) recognized
+by the BIOS, independent of the setting of the root device.
+
+@item Be independent of drive geometry translations
+Unlike many other boot loaders, GRUB makes the particular drive
+translation irrelevant. A drive installed and running with one
+translation may be converted to another translation without any adverse
+effects or changes in GRUB's configuration.
+
+@item Detect all installed @sc{ram}
+GRUB can generally find all the installed @sc{ram} on a PC-compatible
+machine. It uses an advanced BIOS query technique for finding all
+memory regions. As described on the Multiboot Specification (@pxref{Top,
+Multiboot Specification, Motivation, multiboot, The Multiboot
+Specification}), not all kernels make use of this information, but GRUB
+provides it for those who do.
+
+@item Support Logical Block Address mode
+In traditional disk calls (called @dfn{CHS mode}), there is a geometry
+translation problem, that is, the BIOS cannot access over 1024
+cylinders, so the accessible space is limited to at least 508 MB and to
+at most 8GB. GRUB can't universally solve this problem, as there is no
+standard interface used in all machines. However, several newer machines
+have the new interface, Logical Block Address (@dfn{LBA}) mode. GRUB
+automatically detects if LBA mode is available and uses it if
+available. In LBA mode, GRUB can access the entire disk.
+
+@item Support network booting
+GRUB is basically a disk-based boot loader but also has network
+support. You can load OS images from a network by using the @dfn{TFTP}
+protocol.
+
+@item Support remote terminals
+To support computers with no console, GRUB provides remote terminal
+support, so that you can control GRUB from a remote host. Only serial
+terminal support is implemented at the moment.
+@end table
+
+
+@node Role of a boot loader
+@section The role of a boot loader
+
+The following is a quotation from Gordon Matzigkeit, a GRUB fanatic:
+
+@quotation
+Some people like to acknowledge both the operating system and kernel when
+they talk about their computers, so they might say they use
+``GNU/Linux'' or ``GNU/Hurd''. Other people seem to think that the
+kernel is the most important part of the system, so they like to call
+their GNU operating systems ``Linux systems.''
+
+I, personally, believe that this is a grave injustice, because the
+@emph{boot loader} is the most important software of all. I used to
+refer to the above systems as either ``LILO''@footnote{The LInux LOader,
+a boot loader that everybody uses, but nobody likes.} or ``GRUB''
+systems.
+
+Unfortunately, nobody ever understood what I was talking about; now I
+just use the word ``GNU'' as a pseudonym for GRUB.
+
+So, if you ever hear people talking about their alleged ``GNU'' systems,
+remember that they are actually paying homage to the best boot loader
+around@dots{} GRUB!
+@end quotation
+
+We, the GRUB maintainers, do not (usually) encourage Gordon's level of
+fanaticism, but it helps to remember that boot loaders deserve
+recognition. We hope that you enjoy using GNU GRUB as much as we did
+writing it.
+
+
+@node Naming convention
+@chapter Naming convention
+
+The device syntax used in GRUB is a wee bit different from what you may
+have seen before in your operating system(s), and you need to know it so
+that you can specify a drive/partition.
+
+Look at the following examples and explanations:
+
+@example
+(fd0)
+@end example
+
+First of all, GRUB requires that the device name be enclosed with
+@samp{(} and @samp{)}. The @samp{fd} part means that it is a floppy
+disk. The number @samp{0} is the drive number, which is counted from
+@emph{zero}. This expression means that GRUB will use the whole floppy
+disk.
+
+@example
+(hd0,msdos2)
+@end example
+
+Here, @samp{hd} means it is a hard disk drive. The first integer
+@samp{0} indicates the drive number, that is, the first hard disk,
+the string @samp{msdos} indicates the partition scheme, while
+the second integer, @samp{2}, indicates the partition number (or the
+@sc{pc} slice number in the BSD terminology). The partition numbers are
+counted from @emph{one}, not from zero (as was the case in previous
+versions of GRUB). This expression means the second partition of the
+first hard disk drive. In this case, GRUB uses one partition of the
+disk, instead of the whole disk.
+
+@example
+(hd0,msdos5)
+@end example
+
+This specifies the first @dfn{extended partition} of the first hard disk
+drive. Note that the partition numbers for extended partitions are
+counted from @samp{5}, regardless of the actual number of primary
+partitions on your hard disk.
+
+@example
+(hd1,msdos1,bsd1)
+@end example
+
+This means the BSD @samp{a} partition on first @sc{pc} slice number
+of the second hard disk.
+
+Of course, to actually access the disks or partitions with GRUB, you
+need to use the device specification in a command, like @samp{set
+root=(fd0)} or @samp{parttool (hd0,msdos3) hidden-}. To help you find out
+which number specifies a partition you want, the GRUB command-line
+(@pxref{Command-line interface}) options have argument
+completion. This means that, for example, you only need to type
+
+@example
+set root=(
+@end example
+
+followed by a @key{TAB}, and GRUB will display the list of drives,
+partitions, or file names. So it should be quite easy to determine the
+name of your target partition, even with minimal knowledge of the
+syntax.
+
+Note that GRUB does @emph{not} distinguish IDE from SCSI - it simply
+counts the drive numbers from zero, regardless of their type. Normally,
+any IDE drive number is less than any SCSI drive number, although that
+is not true if you change the boot sequence by swapping IDE and SCSI
+drives in your BIOS.
+
+Now the question is, how to specify a file? Again, consider an
+example:
+
+@example
+(hd0,msdos1)/vmlinuz
+@end example
+
+This specifies the file named @samp{vmlinuz}, found on the first
+partition of the first hard disk drive. Note that the argument
+completion works with file names, too.
+
+That was easy, admit it. Now read the next chapter, to find out how to
+actually install GRUB on your drive.
+
+
+@node Installation
+@chapter Installation
+
+In order to install GRUB as your boot loader, you need to first
+install the GRUB system and utilities under your UNIX-like operating
+system (@pxref{Obtaining and Building GRUB}). You can do this either
+from the source tarball, or as a package for your OS.
+
+After you have done that, you need to install the boot loader on a
+drive (floppy or hard disk) by using the utility
+@command{grub-install} (@pxref{Invoking grub-install}) on a UNIX-like OS.
+
+GRUB comes with boot images, which are normally put in the directory
+@file{/usr/lib/grub/<cpu>-<platform>} (for BIOS-based machines
+@file{/usr/lib/grub/i386-pc}). Hereafter, the directory where GRUB images are
+initially placed (normally @file{/usr/lib/grub/<cpu>-<platform>}) will be
+called the @dfn{image directory}, and the directory where the boot
+loader needs to find them (usually @file{/boot}) will be called
+the @dfn{boot directory}.
+
+@menu
+* Installing GRUB using grub-install::
+* Making a GRUB bootable CD-ROM::
+* Device map::
+* BIOS installation::
+@end menu
+
+
+@node Installing GRUB using grub-install
+@section Installing GRUB using grub-install
+
+For information on where GRUB should be installed on PC BIOS platforms,
+@pxref{BIOS installation}.
+
+In order to install GRUB under a UNIX-like OS (such
+as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking
+grub-install}) as the superuser (@dfn{root}).
+
+The usage is basically very simple. You only need to specify one
+argument to the program, namely, where to install the boot loader. The
+argument has to be either a device file (like @samp{/dev/hda}).
+For example, under Linux the following will install GRUB into the MBR
+of the first IDE disk:
+
+@example
+# @kbd{grub-install /dev/hda}
+@end example
+
+Likewise, under GNU/Hurd, this has the same effect:
+
+@example
+# @kbd{grub-install /dev/hd0}
+@end example
+
+But all the above examples assume that GRUB should put images under
+the @file{/boot} directory. If you want GRUB to put images under a directory
+other than @file{/boot}, you need to specify the option
+@option{--boot-directory}. The typical usage is that you create a GRUB
+boot floppy with a filesystem. Here is an example:
+
+@example
+@group
+# @kbd{mke2fs /dev/fd0}
+# @kbd{mount -t ext2 /dev/fd0 /mnt}
+# @kbd{mkdir /mnt/boot}
+# @kbd{grub-install --boot-directory=/mnt/boot /dev/fd0}
+# @kbd{umount /mnt}
+@end group
+@end example
+
+Some BIOSes have a bug of exposing the first partition of a USB drive as a
+floppy instead of exposing the USB drive as a hard disk (they call it
+``USB-FDD'' boot). In such cases, you need to install like this:
+
+@example
+# @kbd{losetup /dev/loop0 /dev/sdb1}
+# @kbd{mount /dev/loop0 /mnt/usb}
+# @kbd{grub-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0}
+@end example
+
+This install doesn't conflict with standard install as long as they are in
+separate directories.
+
+Note that @command{grub-install} is actually just a shell script and the
+real task is done by @command{grub-mkimage} and @command{grub-setup}.
+Therefore, you may run those commands directly to install GRUB, without
+using @command{grub-install}. Don't do that, however, unless you are very
+familiar with the internals of GRUB. Installing a boot loader on a running
+OS may be extremely dangerous.
+
+@node Making a GRUB bootable CD-ROM
+@section Making a GRUB bootable CD-ROM
+
+GRUB supports the @dfn{no emulation mode} in the El Torito
+specification@footnote{El Torito is a specification for bootable CD
+using BIOS functions.}. This means that you can use the whole CD-ROM
+from GRUB and you don't have to make a floppy or hard disk image file,
+which can cause compatibility problems.
+
+For booting from a CD-ROM, GRUB uses a special image called
+@file{cdboot.img}, which is concatenated with @file{core.img}. The
+@file{core.img} used for this should be built with at least the
+@samp{iso9660} and @samp{biosdisk} modules. Your bootable CD-ROM will
+usually also need to include a configuration file @file{grub.cfg} and some
+other GRUB modules.
+
+To make a simple generic GRUB rescue CD, you can use the
+@command{grub-mkrescue} program (@pxref{Invoking grub-mkrescue}):
+
+@example
+$ @kbd{grub-mkrescue -o grub.iso}
+@end example
+
+You will often need to include other files in your image. To do this, first
+make a top directory for the bootable image, say, @samp{iso}:
+
+@example
+$ @kbd{mkdir iso}
+@end example
+
+Make a directory for GRUB:
+
+@example
+$ @kbd{mkdir -p iso/boot/grub}
+@end example
+
+If desired, make the config file @file{grub.cfg} under @file{iso/boot/grub}
+(@pxref{Configuration}), and copy any files and directories for the disc to the
+directory @file{iso/}.
+
+Finally, make the image:
+
+@example
+$ @kbd{grub-mkrescue -o grub.iso iso}
+@end example
+
+This produces a file named @file{grub.iso}, which then can be burned
+into a CD (or a DVD), or written to a USB mass storage device.
+
+The root device will be set up appropriately on entering your
+@file{grub.cfg} configuration file, so you can refer to file names on the CD
+without needing to use an explicit device name. This makes it easier to
+produce rescue images that will work on both optical drives and USB mass
+storage devices.
+
+
+@node Device map
+@section The map between BIOS drives and OS devices
+
+The @command{grub-mkdevicemap} program can be used to create the @dfn{device
+map file}. It is often run automatically by tools such as
+@command{grub-install} if the device map file does not already exist. The
+file name @file{/boot/grub/device.map} is preferred.
+
+If the device map file exists, the GRUB utilities (@command{grub-probe},
+@command{grub-setup}, etc.) read it to map BIOS drives to OS devices. This
+file consists of lines like this:
+
+@example
+@var{device} @var{file}
+@end example
+
+@var{device} is a drive specified in the GRUB syntax (@pxref{Device
+syntax}), and @var{file} is an OS file, which is normally a device file.
+
+Historically, the device map file was used because GRUB device names had to
+be used in the configuration file, and they were derived from BIOS drive
+numbers. The map between BIOS drives and OS devices cannot always be
+guessed correctly: for example, GRUB will get the order wrong if you
+exchange the boot sequence between IDE and SCSI in your BIOS.
+
+Unfortunately, even OS device names are not always stable. Modern versions
+of the Linux kernel may probe drives in a different order from boot to boot,
+and the prefix (@file{/dev/hd*} versus @file{/dev/sd*}) may change depending
+on the driver subsystem in use. As a result, the device map file required
+frequent editing on some systems.
+
+GRUB avoids this problem nowadays by using UUIDs or file system labels when
+generating @file{grub.cfg}, and we advise that you do the same for any
+custom menu entries you write. If the device map file does not exist, then
+the GRUB utilities will assume a temporary device map on the fly. This is
+often good enough, particularly in the common case of single-disk systems.
+
+However, the device map file is not entirely obsolete yet, and there are
+still some situations that require it to exist. If necessary, you may edit
+the file if @command{grub-mkdevicemap} makes a mistake. You can put any
+comments in the file if needed, as the GRUB utilities assume that a line is
+just a comment if the first character is @samp{#}.
+
+
+@node BIOS installation
+@section BIOS installation
+
+@heading MBR
+
+The partition table format traditionally used on PC BIOS platforms is called
+the Master Boot Record (MBR) format; this is the format that allows up to
+four primary partitions and additional logical partitions. With this
+partition table format, there are two ways to install GRUB: it can be
+embedded in the area between the MBR and the first partition (called by
+various names, such as the "boot track", "MBR gap", or "embedding area", and
+which is usually at least 31 KiB), or the core image can be installed in a
+file system and a list of the blocks that make it up can be stored in the
+first sector of that partition.
+
+Each of these has different problems. There is no way to reserve space in
+the embedding area with complete safety, and some proprietary software is
+known to use it to make it difficult for users to work around licensing
+restrictions; and systems are sometimes partitioned without leaving enough
+space before the first partition. On the other hand, installing to a
+filesystem means that GRUB is vulnerable to its blocks being moved around by
+filesystem features such as tail packing, or even by aggressive fsck
+implementations, so this approach is quite fragile; and this approach can
+only be used if the @file{/boot} filesystem is on the same disk that the
+BIOS boots from, so that GRUB does not have to rely on guessing BIOS drive
+numbers.
+
+The GRUB development team generally recommends embedding GRUB before the
+first partition, unless you have special requirements. You must ensure that
+the first partition starts at least 31 KiB (63 sectors) from the start of
+the disk; on modern disks, it is often a performance advantage to align
+partitions on larger boundaries anyway, so the first partition might start 1
+MiB from the start of the disk.
+
+@heading GPT
+
+Some newer systems use the GUID Partition Table (GPT) format. This was
+specified as part of the Extensible Firmware Interface (EFI), but it can
+also be used on BIOS platforms if system software supports it; for example,
+GRUB and GNU/Linux can be used in this configuration. With this format, it
+is possible to reserve a whole partition for GRUB, called the BIOS Boot
+Partition. GRUB can then be embedded into that partition without the risk
+of being overwritten by other software and without being contained in a
+filesystem which might move its blocks around.
+
+When creating a BIOS Boot Partition on a GPT system, you should make sure
+that it is at least 31 KiB in size. (GPT-formatted disks are not usually
+particularly small, so we recommend that you make it larger than the bare
+minimum, such as 1 MiB, to allow plenty of room for growth.) You must also
+make sure that it has the proper partition type. Using GNU Parted, you can
+set this using a command such as the following:
+
+@example
+# @kbd{parted /dev/@var{disk} set @var{partition-number} bios_grub on}
+@end example
+
+If you are using gdisk, set the partition type to @samp{0xEF02}. With
+partitioning programs that require setting the GUID directly, it should be
+@samp{21686148-6449-6e6f-744e656564454649}.
+
+@strong{Caution:} Be very careful which partition you select! When GRUB
+finds a BIOS Boot Partition during installation, it will automatically
+overwrite part of it. Make sure that the partition does not contain any
+other data.
+
+
+@node Booting
+@chapter Booting
+
+GRUB can load Multiboot-compliant kernels in a consistent way,
+but for some free operating systems you need to use some OS-specific
+magic.
+
+@menu
+* General boot methods:: How to boot OSes with GRUB generally
+* OS-specific notes:: Notes on some operating systems
+@end menu
+
+
+@node General boot methods
+@section How to boot operating systems
+
+GRUB has two distinct boot methods. One of the two is to load an
+operating system directly, and the other is to chain-load another boot
+loader which then will load an operating system actually. Generally
+speaking, the former is more desirable, because you don't need to
+install or maintain other boot loaders and GRUB is flexible enough to
+load an operating system from an arbitrary disk/partition. However,
+the latter is sometimes required, since GRUB doesn't support all the
+existing operating systems natively.
+
+@menu
+* Loading an operating system directly::
+* Chain-loading::
+@end menu
+
+
+@node Loading an operating system directly
+@subsection How to boot an OS directly with GRUB
+
+Multiboot (@pxref{Top, Multiboot Specification, Motivation, multiboot,
+The Multiboot Specification}) is the native format supported by GRUB.
+For the sake of convenience, there is also support for Linux, FreeBSD,
+NetBSD and OpenBSD. If you want to boot other operating systems, you
+will have to chain-load them (@pxref{Chain-loading}).
+
+FIXME: this section is incomplete.
+
+@enumerate
+@item
+Run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+However, DOS and Windows have some deficiencies, so you might have to
+use more complicated instructions. @xref{DOS/Windows}, for more
+information.
+
+
+@node Chain-loading
+@subsection Chain-loading an OS
+
+Operating systems that do not support Multiboot and do not have specific
+support in GRUB (specific support is available for Linux, FreeBSD, NetBSD
+and OpenBSD) must be chain-loaded, which involves loading another boot
+loader and jumping to it in real mode.
+
+The @command{chainloader} command (@pxref{chainloader}) is used to set this
+up. It is normally also necessary to load some GRUB modules and set the
+appropriate root device. Putting this together, we get something like this,
+for a Windows system on the first partition of the first hard disk:
+
+@verbatim
+menuentry "Windows" {
+ insmod chain
+ insmod ntfs
+ set root=(hd0,1)
+ chainloader +1
+}
+@end verbatim
+@c FIXME: document UUIDs.
+
+On systems with multiple hard disks, an additional workaround may be
+required. @xref{DOS/Windows}.
+
+Chain-loading is only supported on PC BIOS and EFI platforms.
+
+
+@node OS-specific notes
+@section Some caveats on OS-specific issues
+
+Here, we describe some caveats on several operating systems.
+
+@menu
+* GNU/Hurd::
+* GNU/Linux::
+* DOS/Windows::
+@end menu
+
+
+@node GNU/Hurd
+@subsection GNU/Hurd
+
+Since GNU/Hurd is Multiboot-compliant, it is easy to boot it; there is
+nothing special about it. But do not forget that you have to specify a
+root partition to the kernel.
+
+@enumerate
+@item
+Set GRUB's root device to the same drive as GNU/Hurd's. The command
+@code{search --file --set /boot/gnumach.gz} or similar may help you
+(@pxref{search}).
+
+@item
+Load the kernel and the modules, like this:
+
+@example
+@group
+grub> @kbd{multiboot /boot/gnumach.gz root=device:hd0s1}
+grub> @kbd{module /hurd/ext2fs.static ext2fs --readonly \
+ --multiboot-command-line='$@{kernel-command-line@}' \
+ --host-priv-port='$@{host-port@}' \
+ --device-master-port='$@{device-port@}' \
+ --exec-server-task='$@{exec-task@}' -T typed '$@{root@}' \
+ '$(task-create)' '$(task-resume)'}
+grub> @kbd{module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'}
+@end group
+@end example
+
+@item
+Finally, run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+
+@node GNU/Linux
+@subsection GNU/Linux
+
+It is relatively easy to boot GNU/Linux from GRUB, because it somewhat
+resembles to boot a Multiboot-compliant OS.
+
+@enumerate
+@item
+Set GRUB's root device to the same drive as GNU/Linux's. The command
+@code{search --file --set /vmlinuz} or similar may help you
+(@pxref{search}).
+
+@item
+Load the kernel using the command @command{linux} (@pxref{linux}):
+
+@example
+grub> @kbd{linux /vmlinuz root=/dev/sda1}
+@end example
+
+If you need to specify some kernel parameters, just append them to the
+command. For example, to set @option{acpi} to @samp{off}, do this:
+
+@example
+grub> @kbd{linux /vmlinuz root=/dev/sda1 acpi=off}
+@end example
+
+See the documentation in the Linux source tree for complete information on
+the available options.
+
+With @command{linux} GRUB uses 32-bit protocol. Some BIOS services like APM
+or EDD aren't available with this protocol. In this case you need to use
+@command{linux16}
+
+@example
+grub> @kbd{linux16 /vmlinuz root=/dev/sda1 acpi=off}
+@end example
+
+@item
+If you use an initrd, execute the command @command{initrd} (@pxref{initrd})
+after @command{linux}:
+
+@example
+grub> @kbd{initrd /initrd}
+@end example
+
+If you used @command{linux16} you need to use @command{initrd16}:
+
+@example
+grub> @kbd{initrd16 /initrd}
+@end example
+
+@item
+Finally, run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+@strong{Caution:} If you use an initrd and specify the @samp{mem=}
+option to the kernel to let it use less than actual memory size, you
+will also have to specify the same memory size to GRUB. To let GRUB know
+the size, run the command @command{uppermem} @emph{before} loading the
+kernel. @xref{uppermem}, for more information.
+
+
+@node DOS/Windows
+@subsection DOS/Windows
+
+GRUB cannot boot DOS or Windows directly, so you must chain-load them
+(@pxref{Chain-loading}). However, their boot loaders have some critical
+deficiencies, so it may not work to just chain-load them. To overcome
+the problems, GRUB provides you with two helper functions.
+
+If you have installed DOS (or Windows) on a non-first hard disk, you
+have to use the disk swapping technique, because that OS cannot boot
+from any disks but the first one. The workaround used in GRUB is the
+command @command{drivemap} (@pxref{drivemap}), like this:
+
+@example
+drivemap -s (hd0) (hd1)
+@end example
+
+This performs a @dfn{virtual} swap between your first and second hard
+drive.
+
+@strong{Caution:} This is effective only if DOS (or Windows) uses BIOS
+to access the swapped disks. If that OS uses a special driver for the
+disks, this probably won't work.
+
+Another problem arises if you installed more than one set of DOS/Windows
+onto one disk, because they could be confused if there are more than one
+primary partitions for DOS/Windows. Certainly you should avoid doing
+this, but there is a solution if you do want to do so. Use the partition
+hiding/unhiding technique.
+
+If GRUB @dfn{hides} a DOS (or Windows) partition (@pxref{parttool}), DOS (or
+Windows) will ignore the partition. If GRUB @dfn{unhides} a DOS (or Windows)
+partition, DOS (or Windows) will detect the partition. Thus, if you have
+installed DOS (or Windows) on the first and the second partition of the
+first hard disk, and you want to boot the copy on the first partition, do
+the following:
+
+@example
+@group
+parttool (hd0,1) hidden-
+parttool (hd0,2) hidden+
+set root=(hd0,1)
+chainloader +1
+parttool @verb{'${root}'} boot+
+boot
+@end group
+@end example
+
+
+@node Configuration
+@chapter Writing your own configuration file
+
+GRUB is configured using @file{grub.cfg}, usually located under
+@file{/boot/grub}. This file is quite flexible, but most users will not
+need to write the whole thing by hand.
+
+@menu
+* Simple configuration:: Recommended for most users
+* Shell-like scripting:: For power users and developers
+* Embedded configuration:: Embedding a configuration file into GRUB
+@end menu
+
+
+@node Simple configuration
+@section Simple configuration handling
+
+The program @command{grub-mkconfig} (@pxref{Invoking grub-mkconfig})
+generates @file{grub.cfg} files suitable for most cases. It is suitable for
+use when upgrading a distribution, and will discover available kernels and
+attempt to generate menu entries for them.
+
+@command{grub-mkconfig} does have some limitations. While adding extra
+custom menu entries to the end of the list can be done by editing
+@file{/etc/grub.d/40_custom} or creating @file{/boot/grub/custom.cfg},
+changing the order of menu entries or changing their titles may require
+making complex changes to shell scripts stored in @file{/etc/grub.d/}. This
+may be improved in the future. In the meantime, those who feel that it
+would be easier to write @file{grub.cfg} directly are encouraged to do so
+(@pxref{Booting}, and @ref{Shell-like scripting}), and to disable any system
+provided by their distribution to automatically run @command{grub-mkconfig}.
+
+The file @file{/etc/default/grub} controls the operation of
+@command{grub-mkconfig}. It is sourced by a shell script, and so must be
+valid POSIX shell input; normally, it will just be a sequence of
+@samp{KEY=value} lines, but if the value contains spaces or other special
+characters then it must be quoted. For example:
+
+@example
+GRUB_TERMINAL_INPUT="console serial"
+@end example
+
+Valid keys in @file{/etc/default/grub} are as follows:
+
+@table @samp
+@item GRUB_DEFAULT
+The default menu entry. This may be a number, in which case it identifies
+the Nth entry in the generated menu counted from zero, or the title of a
+menu entry, or the special string @samp{saved}. Using the title may be
+useful if you want to set a menu entry as the default even though there may
+be a variable number of entries before it.
+
+For example, if you have:
+
+@verbatim
+menuentry 'Example GNU/Linux distribution' --class gnu-linux {
+ ...
+}
+@end verbatim
+
+then you can make this the default using:
+
+@example
+GRUB_DEFAULT='Example GNU/Linux distribution'
+@end example
+
+If you set this to @samp{saved}, then the default menu entry will be that
+saved by @samp{GRUB_SAVEDEFAULT}, @command{grub-set-default}, or
+@command{grub-reboot}.
+
+The default is @samp{0}.
+
+@item GRUB_SAVEDEFAULT
+If this option is set to @samp{true}, then, when an entry is selected, save
+it as a new default entry for use by future runs of GRUB. This is only
+useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because
+@samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with
+@command{grub-set-default} or @command{grub-reboot}. Unset by default.
+This option relies on the environment block, which may not be available in
+all situations (@pxref{Environment block}).
+
+@item GRUB_TIMEOUT
+Boot the default entry this many seconds after the menu is displayed, unless
+a key is pressed. The default is @samp{5}. Set to @samp{0} to boot
+immediately without displaying the menu, or to @samp{-1} to wait
+indefinitely.
+
+@item GRUB_HIDDEN_TIMEOUT
+Wait this many seconds for a key to be pressed before displaying the menu.
+If no key is pressed during that time, boot immediately. Unset by default.
+
+@item GRUB_HIDDEN_TIMEOUT_QUIET
+In conjunction with @samp{GRUB_HIDDEN_TIMEOUT}, set this to @samp{true} to
+suppress the verbose countdown while waiting for a key to be pressed before
+displaying the menu. Unset by default.
+
+@item GRUB_DEFAULT_BUTTON
+@itemx GRUB_TIMEOUT_BUTTON
+@itemx GRUB_HIDDEN_TIMEOUT_BUTTON
+@itemx GRUB_BUTTON_CMOS_ADDRESS
+Variants of the corresponding variables without the @samp{_BUTTON} suffix,
+used to support vendor-specific power buttons. @xref{Vendor power-on keys}.
+
+@item GRUB_DISTRIBUTOR
+Set by distributors of GRUB to their identifying name. This is used to
+generate more informative menu entry titles.
+
+@item GRUB_TERMINAL_INPUT
+Select the terminal input device. You may select multiple devices here,
+separated by spaces.
+
+Valid terminal input names depend on the platform, but may include
+@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal),
+@samp{ofconsole} (Open Firmware console), @samp{at_keyboard} (PC AT
+keyboard, mainly useful with Coreboot), or @samp{usb_keyboard} (USB keyboard
+using the HID Boot Protocol, for cases where the firmware does not handle
+this).
+
+The default is to use the platform's native terminal input.
+
+@item GRUB_TERMINAL_OUTPUT
+Select the terminal output device. You may select multiple devices here,
+separated by spaces.
+
+Valid terminal output names depend on the platform, but may include
+@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal),
+@samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware
+console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot).
+
+The default is to use the platform's native terminal output.
+
+@item GRUB_TERMINAL
+If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and
+@samp{GRUB_TERMINAL_OUTPUT} to the same value.
+
+@item GRUB_SERIAL_COMMAND
+A command to configure the serial port when using the serial console.
+@xref{serial}. Defaults to @samp{serial}.
+
+@item GRUB_CMDLINE_LINUX
+Command-line arguments to add to menu entries for the Linux kernel.
+
+@item GRUB_CMDLINE_LINUX_DEFAULT
+Unless @samp{GRUB_DISABLE_RECOVERY} is set to @samp{true}, two menu
+entries will be generated for each Linux kernel: one default entry and one
+entry for recovery mode. This option lists command-line arguments to add
+only to the default menu entry, after those listed in
+@samp{GRUB_CMDLINE_LINUX}.
+
+@item GRUB_CMDLINE_NETBSD
+@itemx GRUB_CMDLINE_NETBSD_DEFAULT
+As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for
+NetBSD.
+
+@item GRUB_CMDLINE_XEN
+@itemx GRUB_CMDLINE_XEN_DEFAULT
+As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for
+Linux and Xen.
+
+@item GRUB_DISABLE_LINUX_UUID
+Normally, @command{grub-mkconfig} will generate menu entries that use
+universally-unique identifiers (UUIDs) to identify the root filesystem to
+the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is
+usually more reliable, but in some cases it may not be appropriate. To
+disable the use of UUIDs, set this option to @samp{true}.
+
+@item GRUB_DISABLE_RECOVERY
+If this option is set to @samp{true}, disable the generation of recovery
+mode menu entries.
+
+@item GRUB_VIDEO_BACKEND
+If graphical video support is required, either because the @samp{gfxterm}
+graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set,
+then @command{grub-mkconfig} will normally load all available GRUB video
+drivers and use the one most appropriate for your hardware. If you need to
+override this for some reason, then you can set this option.
+
+After @command{grub-install} has been run, the available video drivers are
+listed in @file{/boot/grub/video.lst}.
+
+@item GRUB_GFXMODE
+Set the resolution used on the @samp{gfxterm} graphical terminal. Note that
+you can only use modes which your graphics card supports via VESA BIOS
+Extensions (VBE), so for example native LCD panel resolutions may not be
+available. The default is @samp{640x480}. @xref{gfxmode}.
+
+@item GRUB_BACKGROUND
+Set a background image for use with the @samp{gfxterm} graphical terminal.
+The value of this option must be a file readable by GRUB at boot time, and
+it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}.
+The image will be scaled if necessary to fit the screen.
+
+@item GRUB_THEME
+Set a theme for use with the @samp{gfxterm} graphical terminal.
+
+@item GRUB_GFXPAYLOAD_LINUX
+Set to @samp{text} to force the Linux kernel to boot in normal text mode,
+@samp{keep} to preserve the graphics mode set using @samp{GRUB_GFXMODE},
+@samp{@var{width}x@var{height}}[@samp{x@var{depth}}] to set a particular
+graphics mode, or a sequence of these separated by commas or semicolons to
+try several modes in sequence. @xref{gfxpayload}.
+
+Depending on your kernel, your distribution, your graphics card, and the
+phase of the moon, note that using this option may cause GNU/Linux to suffer
+from various display problems, particularly during the early part of the
+boot sequence. If you have problems, set this option to @samp{text} and
+GRUB will tell Linux to boot in normal text mode.
+
+@item GRUB_DISABLE_OS_PROBER
+Normally, @command{grub-mkconfig} will try to use the external
+@command{os-prober} program, if installed, to discover other operating
+systems installed on the same system and generate appropriate menu entries
+for them. Set this option to @samp{true} to disable this.
+
+@item GRUB_INIT_TUNE
+Play a tune on the speaker when GRUB starts. This is particularly useful
+for users unable to see the screen. The value of this option is passed
+directly to @ref{play}.
+
+@item GRUB_BADRAM
+If this option is set, GRUB will issue a @ref{badram} command to filter
+out specified regions of RAM.
+
+@item GRUB_PRELOAD_MODULES
+This option may be set to a list of GRUB module names separated by spaces.
+Each module will be loaded as early as possible, at the start of
+@file{grub.cfg}.
+
+@end table
+
+For more detailed customisation of @command{grub-mkconfig}'s output, you may
+edit the scripts in @file{/etc/grub.d} directly.
+@file{/etc/grub.d/40_custom} is particularly useful for adding entire custom
+menu entries; simply type the menu entries you want to add at the end of
+that file, making sure to leave at least the first two lines intact.
+
+
+@node Shell-like scripting
+@section Writing full configuration files directly
+
+@c Some of this section is derived from the GNU Bash manual page, also
+@c copyrighted by the FSF.
+
+@file{grub.cfg} is written in GRUB's built-in scripting language, which has
+a syntax quite similar to that of GNU Bash and other Bourne shell
+derivatives.
+
+@heading Words
+
+A @dfn{word} is a sequence of characters considered as a single unit by
+GRUB. Words are separated by @dfn{metacharacters}, which are the following
+plus space, tab, and newline:
+
+@example
+@{ @} | & $ ; < >
+@end example
+
+Quoting may be used to include metacharacters in words; see below.
+
+@heading Reserved words
+
+Reserved words have a special meaning to GRUB. The following words are
+recognised as reserved when unquoted and either the first word of a simple
+command or the third word of a @code{for} command:
+
+@example
+! [[ ]] @{ @}
+case do done elif else esac fi for function
+if in menuentry select then time until while
+@end example
+
+Not all of these reserved words have a useful purpose yet; some are reserved
+for future expansion.
+
+@heading Quoting
+
+Quoting is used to remove the special meaning of certain characters or
+words. It can be used to treat metacharacters as part of a word, to prevent
+reserved words from being recognised as such, and to prevent variable
+expansion.
+
+There are three quoting mechanisms: the escape character, single quotes, and
+double quotes.
+
+A non-quoted backslash (\) is the @dfn{escape character}. It preserves the
+literal value of the next character that follows, with the exception of
+newline.
+
+Enclosing characters in single quotes preserves the literal value of each
+character within the quotes. A single quote may not occur between single
+quotes, even when preceded by a backslash.
+
+Enclosing characters in double quotes preserves the literal value of all
+characters within the quotes, with the exception of @samp{$} and @samp{\}.
+The @samp{$} character retains its special meaning within double quotes.
+The backslash retains its special meaning only when followed by one of the
+following characters: @samp{$}, @samp{"}, @samp{\}, or newline. A
+backslash-newline pair is treated as a line continuation (that is, it is
+removed from the input stream and effectively ignored@footnote{Currently a
+backslash-newline pair within a variable name is not handled properly, so
+use this feature with some care.}). A double quote may be quoted within
+double quotes by preceding it with a backslash.
+
+@heading Variable expansion
+
+The @samp{$} character introduces variable expansion. The variable name to
+be expanded may be enclosed in braces, which are optional but serve to
+protect the variable to be expanded from characters immediately following it
+which could be interpreted as part of the name.
+
+Normal variable names begin with an alphabetic character, followed by zero
+or more alphanumeric characters. These names refer to entries in the GRUB
+environment (@pxref{Environment}).
+
+Positional variable names consist of one or more digits. They represent
+parameters passed to function calls, with @samp{$1} representing the first
+parameter, and so on.
+
+The special variable name @samp{?} expands to the exit status of the most
+recently executed command. When positional variable names are active, other
+special variable names @samp{@@}, @samp{*} and @samp{#} are defined and they
+expand to all positional parameters with necessary quoting, positional
+parameters without any quoting, and positional parameter count respectively.
+
+@heading Comments
+
+A word beginning with @samp{#} causes that word and all remaining characters
+on that line to be ignored.
+
+@heading Simple commands
+
+A @dfn{simple command} is a sequence of words separated by spaces or tabs
+and terminated by a semicolon or a newline. The first word specifies the
+command to be executed. The remaining words are passed as arguments to the
+invoked command.
+
+The return value of a simple command is its exit status. If the reserved
+word @code{!} precedes the command, then the return value is instead the
+logical negation of the command's exit status.
+
+@heading Compound commands
+
+A @dfn{compound command} is one of the following:
+
+@table @asis
+@item for @var{name} in @var{word} @dots{}; do @var{list}; done
+The list of words following @code{in} is expanded, generating a list of
+items. The variable @var{name} is set to each element of this list in turn,
+and @var{list} is executed each time. The return value is the exit status
+of the last command that executes. If the expansion of the items following
+@code{in} results in an empty list, no commands are executed, and the return
+status is 0.
+
+@item if @var{list}; then @var{list}; [elif @var{list}; then @var{list};] @dots{} [else @var{list};] fi
+The @code{if} @var{list} is executed. If its exit status is zero, the
+@code{then} @var{list} is executed. Otherwise, each @code{elif} @var{list}
+is executed in turn, and if its exit status is zero, the corresponding
+@code{then} @var{list} is executed and the command completes. Otherwise,
+the @code{else} @var{list} is executed, if present. The exit status is the
+exit status of the last command executed, or zero if no condition tested
+true.
+
+@item while @var{cond}; do @var{list}; done
+@itemx until @var{cond}; do @var{list}; done
+The @code{while} command continuously executes the @code{do} @var{list} as
+long as the last command in @var{cond} returns an exit status of zero. The
+@code{until} command is identical to the @code{while} command, except that
+the test is negated; the @code{do} @var{list} is executed as long as the
+last command in @var{cond} returns a non-zero exit status. The exit status
+of the @code{while} and @code{until} commands is the exit status of the last
+@code{do} @var{list} command executed, or zero if none was executed.
+
+@item function @var{name} @{ @var{command}; @dots{} @}
+This defines a function named @var{name}. The @dfn{body} of the function is
+the list of commands within braces, each of which must be terminated with a
+semicolon or a newline. This list of commands will be executed whenever
+@var{name} is specified as the name of a simple command. Function
+definitions do not affect the exit status in @code{$?}. When executed, the
+exit status of a function is the exit status of the last command executed in
+the body.
+
+@item menuentry @var{title} [@option{--class=class} @dots{}] [@option{--users=users}] [@option{--hotkey=key}] @{ @var{command}; @dots{} @}
+@xref{menuentry}.
+@end table
+
+@heading Built-in Commands
+
+Some built-in commands are also provided by GRUB script to help script
+writers perform actions that are otherwise not possible. For example, these
+include commands to jump out of a loop without fully completing it, etc.
+
+@table @asis
+@item break [@code{n}]
+Exit from within a @code{for}, @code{while}, or @code{until} loop. If
+@code{n} is specified, break @code{n} levels. @code{n} must be greater than
+or equal to 1. If @code{n} is greater than the number of enclosing loops,
+all enclosing loops are exited. The return value is 0 unless @code{n} is
+not greater than or equal to 1.
+
+@item continue [@code{n}]
+Resume the next iteration of the enclosing @code{for}, @code{while} or
+@code{until} loop. If @code{n} is specified, resume at the @code{n}th
+enclosing loop. @code{n} must be greater than or equal to 1. If @code{n}
+is greater than the number of enclosing loops, the last enclosing loop (the
+@dfn{top-level} loop) is resumed. The return value is 0 unless @code{n} is
+not greater than or equal to 1.
+
+@item return [@code{n}]
+Causes a function to exit with the return value specified by @code{n}. If
+@code{n} is omitted, the return status is that of the last command executed
+in the function body. If used outside a function the return status is
+false.
+
+@item shift [@code{n}]
+The positional parameters from @code{n}+1 @dots{} are renamed to
+@code{$1}@dots{}. Parameters represented by the numbers @code{$#} down to
+@code{$#}-@code{n}+1 are unset. @code{n} must be a non-negative number less
+than or equal to @code{$#}. If @code{n} is 0, no parameters are changed.
+If @code{n} is not given, it is assumed to be 1. If @code{n} is greater
+than @code{$#}, the positional parameters are not changed. The return
+status is greater than zero if @code{n} is greater than @code{$#} or less
+than zero; otherwise 0.
+
+@end table
+
+@node Embedded configuration
+@section Embedding a configuration file into GRUB
+
+GRUB supports embedding a configuration file directly into the core image,
+so that it is loaded before entering normal mode. This is useful, for
+example, when it is not straightforward to find the real configuration file,
+or when you need to debug problems with loading that file.
+@command{grub-install} uses this feature when it is not using BIOS disk
+functions or when installing to a different disk from the one containing
+@file{/boot/grub}, in which case it needs to use the @command{search}
+command (@pxref{search}) to find @file{/boot/grub}.
+
+To embed a configuration file, use the @option{-c} option to
+@command{grub-mkimage}. The file is copied into the core image, so it may
+reside anywhere on the file system, and may be removed after running
+@command{grub-mkimage}.
+
+After the embedded configuration file (if any) is executed, GRUB will load
+the @samp{normal} module (@pxref{normal}), which will then read the real
+configuration file from @file{$prefix/grub.cfg}. By this point, the
+@code{root} variable will also have been set to the root device name. For
+example, @code{prefix} might be set to @samp{(hd0,1)/boot/grub}, and
+@code{root} might be set to @samp{hd0,1}. Thus, in most cases, the embedded
+configuration file only needs to set the @code{prefix} and @code{root}
+variables, and then drop through to GRUB's normal processing. A typical
+example of this might look like this:
+
+@example
+@group
+search.fs_uuid 01234567-89ab-cdef-0123-456789abcdef root
+set prefix=($root)/boot/grub
+@end group
+@end example
+
+(The @samp{search_fs_uuid} module must be included in the core image for this
+example to work.)
+
+In more complex cases, it may be useful to read other configuration files
+directly from the embedded configuration file. This allows such things as
+reading files not called @file{grub.cfg}, or reading files from a directory
+other than that where GRUB's loadable modules are installed. To do this,
+include the @samp{configfile} and @samp{normal} modules in the core image,
+and embed a configuration file that uses the @command{configfile} command to
+load another file. The following example of this also requires the
+@command{echo}, @command{search_label}, and @command{test} modules to be
+included in the core image:
+
+@example
+@group
+search.fs_label grub root
+if [ -e /boot/grub/example/test1.cfg ]; then
+ set prefix=($root)/boot/grub
+ configfile /boot/grub/example/test1.cfg
+else
+ if [ -e /boot/grub/example/test2.cfg ]; then
+ set prefix=($root)/boot/grub
+ configfile /boot/grub/example/test2.cfg
+ else
+ echo "Could not find an example configuration file!"
+ fi
+fi
+@end group
+@end example
+
+The embedded configuration file may not contain menu entries directly, but
+may only read them from elsewhere using @command{configfile}.
+
+@node Theme file format
+@chapter Theme file format
+@section Introduction
+The GRUB graphical menu supports themes that can customize the layout and
+appearance of the GRUB boot menu. The theme is configured through a plain
+text file that specifies the layout of the various GUI components (including
+the boot menu, timeout progress bar, and text messages) as well as the
+appearance using colors, fonts, and images. Example is available in docs/example_theme.txt
+
+@section Theme Elements
+@subsection Colors
+
+Colors can be specified in several ways:
+
+@itemize
+@item HTML-style ``#RRGGBB'' or ``#RGB'' format, where *R*, *G*, and *B* are hexadecimal digits (e.g., ``#8899FF'')
+@item as comma-separated decimal RGB values (e.g., ``128, 128, 255'')
+@item with ``SVG 1.0 color names'' (e.g., ``cornflowerblue'') which must be specified in lowercase.
+@end itemize
+@subsection Fonts
+The fonts GRUB uses ``PFF2 font format'' bitmap fonts. Fonts are specified
+with full font names. Currently there is no
+provision for a preference list of fonts, or deriving one font from another.
+Fonts are loaded with the ``loadfont'' command in GRUB. To see the list of
+loaded fonts, execute the ``lsfonts'' command. If there are too many fonts to
+fit on screen, do ``set pager=1'' before executing ``lsfonts''.
+
+
+@subsection Progress Bar
+
+@float Figure, Pixmap-styled progress bar
+@c @image{Theme_progress_bar,,,,.png}
+@end float
+
+@float Figure, Plain progress bar, drawn with solid color.
+@c @image{Theme_progress_bar_filled,,,,.png}
+@end float
+
+Progress bars are used to display the remaining time before GRUB boots the
+default menu entry. To create a progress bar that will display the remaining
+time before automatic boot, simply create a ``progress_bar'' component with
+the id ``__timeout__''. This indicates to GRUB that the progress bar should
+be updated as time passes, and it should be made invisible if the countdown to
+automatic boot is interrupted by the user.
+
+Progress bars may optionally have text displayed on them. This is controlled
+through the ``show_text'' property, which can be set to either ``true'' or
+``false'' to control whether text is displayed. When GRUB is counting down to
+automatic boot, the text informs the user of the number of seconds remaining.
+
+
+@subsection Circular Progress Indicator
+
+@c @image{Theme_circular_progress,,,,.png}
+
+The circular progress indicator functions similarly to the progress bar. When
+given an id of ``__timeout__'', GRUB updates the circular progress indicator's
+value to indicate the time remaining. For the circular progress indicator,
+there are two images used to render it: the *center* image, and the *tick*
+image. The center image is rendered in the center of the component, while the
+tick image is used to render each mark along the circumference of the
+indicator.
+
+
+@subsection Labels
+
+Text labels can be placed on the boot screen. The font, color, and horizontal
+alignment can be specified for labels. If a label is given the id
+``__timeout__'', then the ``text'' property for that label is also updated
+with a message informing the user of the number of seconds remaining until
+automatic boot. This is useful in case you want the text displayed somewhere
+else instead of directly on the progress bar.
+
+
+@subsection Boot Menu
+
+@c @image{Theme_boot_menu,,,,.png}
+
+The boot menu where GRUB displays the menu entries from the ``grub.cfg'' file.
+It is a list of items, where each item has a title and an optional icon. The
+icon is selected based on the *classes* specified for the menu entry. If
+there is a PNG file named ``myclass.png'' in the ``grub/themes/icons''
+directory, it will be displayed for items which have the class *myclass*. The
+boot menu can be customized in several ways, such as the font and color used
+for the menu entry title, and by specifying styled boxes for the menu itself
+and for the selected item highlight.
+
+
+@subsection Styled Boxes
+
+One of the most important features for customizing the layout is the use of
+ *styled boxes*. A styled box is composed of 9 rectangular (and potentially
+empty) regions, which are used to seamlessly draw the styled box on screen:
+
+@multitable @columnfractions 0.3 0.3 0.3
+@item Northwest (nw) @tab North (n) @tab Northeast (ne)
+@item West (w) @tab Center (c) @tab East (e)
+@item Southwest (sw) @tab South (s) @tab Southeast (se)
+@end multitable
+
+To support any size of box on screen, the center slice and the slices for the
+top, bottom, and sides are all scaled to the correct size for the component on
+screen, using the following rules:
+
+@enumerate
+@item The edge slices (north, south, east, and west) are scaled in the direction of the edge they are adjacent to. For instance, the west slice is scaled vertically.
+@item The corner slices (northwest, northeast, southeast, and southwest) are not scaled.
+@item The center slice is scaled to fill the remaining space in the middle.
+@end enumerate
+
+As an example of how an image might be sliced up, consider the styled box
+used for a terminal view.
+
+@float Figure, An example of the slices (in red) used for a terminal window. This drawing was created and sliced in Inkscape_, as the next section explains.
+@c @image{Box_slice_example_terminal,,,,.png}
+@end float
+
+@subsection Creating Styled Box Images
+
+The Inkscape_ scalable vector graphics editor is a very useful tool for
+creating styled box images. One process that works well for slicing a drawing
+into the necessary image slices is:
+
+@enumerate
+@item Create or open the drawing you'd like use.
+@item Create a new layer on the top of the layer stack. Make it visible. Select this layer as the current layer.
+@item Draw 9 rectangles on your drawing where you'd like the slices to be. Clear the fill option, and set the stroke to 1 pixel wide solid stroke. The corners of the slices must meet precisely; if it is off by a single pixel, it will probably be evident when the styled box is rendered in the GRUB menu. You should probably go to File | Document Properties | Grids and enable a grid or create a guide (click on one of the rulers next to the drawing and drag over the drawing; release the mouse button to place the guide) to help place the rectangles precisely.
+@item Right click on the center slice rectangle and choose Object Properties. Change the "Id" to ``slice_c`` and click Set. Repeat this for the remaining 8 rectangles, giving them Id values of ``slice_n``, ``slice_ne``, ``slice_e``, and so on according to the location.
+@item Save the drawing.
+@item Select all the slice rectangles. With the slice layer selected, you can simply press Ctrl+A to select all rectangles. The status bar should indicate that 9 rectangles are selected.
+@item Click the layer hide icon for the slice layer in the layer palette. The rectangles will remain selected, even though they are hidden.
+@item Choose File | Export Bitmap and check the *Batch export 9 selected objects* box. Make sure that *Hide all except selected* is unchecked. click *Export*. This will create PNG files in the same directory as the drawing, named after the slices. These can now be used for a styled box in a GRUB theme.
+@end enumerate
+
+@section Theme File Manual
+
+The theme file is a plain text file. Lines that begin with ``#`` are ignored
+and considered comments. (Note: This may not be the case if the previous line
+ended where a value was expected.)
+
+The theme file contains two types of statements:
+@enumerate
+@item Global properties.
+@item Component construction.
+@end enumerate
+
+@subsection Global Properties
+
+@subsection Format
+
+Global properties are specified with the simple format:
+@itemize
+@item name1: value1
+@item name2: "value which may contain spaces"
+@item name3: #88F
+@end itemize
+
+In this example, name3 is assigned a color value.
+
+
+@subsection Global Property List
+
+@multitable @columnfractions 0.3 0.6
+@item title-text @tab Specifies the text to display at the top center of the screen as a title.
+@item title-font @tab Defines the font used for the title message at the top of the screen.
+@item title-color @tab Defines the color of the title message.
+@item message-font @tab Defines the font used for messages, such as when GRUB is unable to automatically boot an entry.
+@item message-color @tab Defines the color of the message text.
+@item message-bg-color @tab Defines the background color of the message text area.
+@item desktop-image @tab Specifies the image to use as the background. It will be scaled to fit the screen size.
+@item desktop-color @tab Specifies the color for the background if *desktop-image* is not specified.
+@item terminal-box @tab Specifies the file name pattern for the styled box slices used for the command line terminal window. For example, ``terminal-box: terminal_*.png'' will use the images ``terminal_c.png`` as the center area, ``terminal_n.png`` as the north (top) edge, ``terminal_nw.png`` as the northwest (upper left) corner, and so on. If the image for any slice is not found, it will simply be left empty.
+@end multitable
+
+
+@subsection Component Construction
+
+Greater customizability comes is provided by components. A tree of components
+forms the user interface. *Containers* are components that can contain other
+components, and there is always a single root component which is an instance
+of a *canvas* container.
+
+Components are created in the theme file by prefixing the type of component
+with a '+' sign:
+
+@code{ + label @{ text="GRUB" font="aqui 11" color="#8FF" @} }
+
+properties of a component are specified as "name = value" (whitespace
+surrounding tokens is optional and is ignored) where *value* may be:
+@itemize
+@item a single word (e.g., ``align = center``, ``color = #FF8080``),
+@item a quoted string (e.g., ``text = "Hello, World!"``), or
+@item a tuple (e.g., ``preferred_size = (120, 80)``).
+@end itemize
+
+@subsection Component List
+
+The following is a list of the components and the properties they support.
+
+@itemize
+@item label
+ A label displays a line of text.
+
+ Properties:
+ @multitable @columnfractions 0.2 0.7
+ @item text @tab The text to display.
+ @item font @tab The font to use for text display.
+ @item color @tab The color of the text.
+ @item align @tab The horizontal alignment of the text within the component. Options are ``left``, ``center``, and ``right``.
+ @end multitable
+
+@item image
+ A component that displays an image. The image is scaled to fit the
+ component, although the preferred size defaults to the image's original
+ size unless the ``preferred_size`` property is explicitly set.
+
+ Properties:
+
+ @multitable @columnfractions 0.2 0.7
+ @item file @tab The full path to the image file to load.
+ @end multitable
+
+@item progress_bar
+ Displays a horizontally oriented progress bar. It can be rendered using
+ simple solid filled rectangles, or using a pair of pixmap styled boxes.
+
+ Properties:
+
+ @multitable @columnfractions 0.2 0.7
+ @item fg_color @tab The foreground color for plain solid color rendering.
+ @item bg_color @tab The background color for plain solid color rendering.
+ @item border_color @tab The border color for plain solid color rendering.
+ @item text_color @tab The text color.
+ @item show_text @tab Boolean value indicating whether or not text should be displayed on the progress bar. If set to *false*, then no text will be displayed on the bar. If set to any other value, text will be displayed on the bar.
+ @item bar_style @tab The styled box specification for the frame of the progress bar. Example: ``progress_frame_*.png``
+ @item highlight_style @tab The styled box specification for the highlighted region of the progress bar. This box will be used to paint just the highlighted region of the bar, and will be increased in size as the bar nears completion. Example: ``progress_hl_*.png``.
+ @item text @tab The text to display on the progress bar. If the progress bar's ID is set to ``__timeout__``, then GRUB will updated this property with an informative message as the timeout approaches.
+ @item value @tab The progress bar current value. Normally not set manually.
+ @item start @tab The progress bar start value. Normally not set manually.
+ @item end @tab The progress bar end value. Normally not set manually.
+ @end multitable
+
+@item circular_progress
+ Displays a circular progress indicator. The appearance of this component
+ is determined by two images: the *center* image and the *tick* image. The
+ center image is generally larger and will be drawn in the center of the
+ component. Around the circumference of a circle within the component, the
+ tick image will be drawn a certain number of times, depending on the
+ properties of the component.
+
+ Properties:
+
+ @multitable @columnfractions 0.3 0.6
+ @item center_bitmap
+ @tab The file name of the image to draw in the center of the component.
+ @item tick_bitmap
+ @tab The file name of the image to draw for the tick marks.
+ @item num_ticks
+ @tab The number of ticks that make up a full circle.
+ @item ticks_disappear
+ @tab Boolean value indicating whether tick marks should progressively appear,
+ or progressively disappear as *value* approaches *end*. Specify
+ ``true`` or ``false``.
+ @item value
+ @tab The progress indicator current value. Normally not set manually.
+ @item start
+ @tab The progress indicator start value. Normally not set manually.
+ @item end
+ @tab The progress indicator end value. Normally not set manually.
+ @end multitable
+@item boot_menu
+ Displays the GRUB boot menu. It allows selecting items and executing them.
+
+ Properties:
+
+ @multitable @columnfractions 0.4 0.5
+ @item item_font
+ @tab The font to use for the menu item titles.
+ @item selected_item_font
+ @tab The font to use for the selected menu item, or ``inherit`` (the default)
+ to use ``item_font`` for the selected menu item as well.
+ @item item_color
+ @tab The color to use for the menu item titles.
+ @item selected_item_color
+ @tab The color to use for the selected menu item, or ``inherit`` (the default)
+ to use ``item_color`` for the selected menu item as well.
+ @item icon_width
+ @tab The width of menu item icons. Icons are scaled to the specified size.
+ @item icon_height
+ @tab The height of menu item icons.
+ @item item_height
+ @tab The height of each menu item in pixels.
+ @item item_padding
+ @tab The amount of space in pixels to leave on each side of the menu item
+ contents.
+ @item item_icon_space
+ @tab The space between an item's icon and the title text, in pixels.
+ @item item_spacing
+ @tab The amount of space to leave between menu items, in pixels.
+ @item menu_pixmap_style
+ @tab The image file pattern for the menu frame styled box.
+ Example: ``menu_*.png`` (this will use images such as ``menu_c.png``,
+ ``menu_w.png``, `menu_nw.png``, etc.)
+ @item selected_item_pixmap_style
+ @tab The image file pattern for the selected item highlight styled box.
+ @item scrollbar
+ @tab Boolean value indicating whether the scroll bar should be drawn if the
+ frame and thumb styled boxes are configured.
+ @item scrollbar_frame
+ @tab The image file pattern for the entire scroll bar.
+ Example: ``scrollbar_*.png``
+ @item scrollbar_thumb
+ @tab The image file pattern for the scroll bar thumb (the part of the scroll
+ bar that moves as scrolling occurs).
+ Example: ``scrollbar_thumb_*.png``
+ @item max_items_shown
+ @tab The maximum number of items to show on the menu. If there are more than
+ *max_items_shown* items in the menu, the list will scroll to make all
+ items accessible.
+ @end multitable
+
+@item canvas
+ Canvas is a container that allows manual placement of components within it.
+ It does not alter the positions of its child components. It assigns all
+ child components their preferred sizes.
+
+@item hbox
+ The *hbox* container lays out its children from left to right, giving each
+ one its preferred width. The height of each child is set to the maximum of
+ the preferred heights of all children.
+
+@item vbox
+ The *vbox* container lays out its children from top to bottom, giving each
+ one its preferred height. The width of each child is set to the maximum of
+ the preferred widths of all children.
+@end itemize
+
+
+@subsection Common properties
+
+The following properties are supported by all components:
+@table @samp
+@item left
+ The distance from the left border of container to left border of the object in either of three formats:
+ @multitable @columnfractions 0.2 0.7
+ @item x @tab Value in pixels
+ @item p% @tab Percentage
+ @item p%+x @tab mixture of both
+ @end multitable
+@item top
+ The distance from the left border of container to left border of the object in same format.
+@item width
+ The width of object in same format.
+@item height
+ The height of object in same format.
+@item id
+ The identifier for the component. This can be any arbitrary string.
+ The ID can be used by scripts to refer to various components in the GUI
+ component tree. Currently, there is one special ID value that GRUB
+ recognizes:
+
+ @multitable @columnfractions 0.2 0.7
+ @item ``__timeout__`` @tab Any component with this ID will have its *text*, *start*, *end*, *value*, and *visible* properties set by GRUB when it is counting down to an automatic boot of the default menu entry.
+ @end multitable
+@end table
+
+
+
+@node Network
+@chapter Booting GRUB from the network
+
+The following instructions only work on PC BIOS systems where the Preboot
+eXecution Environment (PXE) is available.
+
+To generate a PXE boot image, run:
+
+@example
+@group
+grub-mkimage --format=i386-pc-pxe --output=grub.pxe --prefix='(pxe)/boot/grub' pxe pxecmd
+@end group
+@end example
+
+Copy @file{grub.pxe}, @file{/boot/grub/*.mod}, and @file{/boot/grub/*.lst}
+to the PXE (TFTP) server, ensuring that @file{*.mod} and @file{*.lst} are
+accessible via the @file{/boot/grub/} path from the TFTP server root. Set
+the DHCP server configuration to offer @file{grub.pxe} as the boot file (the
+@samp{filename} option in ISC dhcpd).
+
+You can also use the @command{grub-mknetdir} utility to generate an image
+and a GRUB directory tree, rather than copying files around manually.
+
+After GRUB has started, files on the TFTP server will be accessible via the
+@samp{(pxe)} device.
+
+The server and gateway IP address can be controlled by changing the
+@samp{(pxe)} device name to @samp{(pxe:@var{server-ip})} or
+@samp{(pxe:@var{server-ip}:@var{gateway-ip})}. Note that this should be
+changed both in the prefix and in any references to the device name in the
+configuration file.
+
+GRUB provides several environment variables which may be used to inspect or
+change the behaviour of the PXE device:
+
+@table @samp
+@item net_pxe_ip
+The IP address of this machine. Read-only.
+
+@item net_pxe_mac
+The network interface's MAC address. Read-only.
+
+@item net_pxe_hostname
+The client host name provided by DHCP. Read-only.
+
+@item net_pxe_domain
+The client domain name provided by DHCP. Read-only.
+
+@item net_pxe_rootpath
+The path to the client's root disk provided by DHCP. Read-only.
+
+@item net_pxe_extensionspath
+The path to additional DHCP vendor extensions provided by DHCP. Read-only.
+
+@item net_pxe_boot_file
+The boot file name provided by DHCP. Read-only.
+
+@item net_pxe_dhcp_server_name
+The name of the DHCP server responsible for these boot parameters.
+Read-only.
+
+@item pxe_blksize
+The PXE transfer block size. Read-write, defaults to 512.
+
+@item pxe_default_server
+The default PXE server. Read-write, although setting this is only useful
+before opening a PXE device.
+
+@item pxe_default_gateway
+The default gateway to use when contacting the PXE server. Read-write,
+although setting this is only useful before opening a PXE device.
+@end table
+
+
+@node Serial terminal
+@chapter Using GRUB via a serial line
+
+This chapter describes how to use the serial terminal support in GRUB.
+
+If you have many computers or computers with no display/keyboard, it
+could be very useful to control the computers through serial
+communications. To connect one computer with another via a serial line,
+you need to prepare a null-modem (cross) serial cable, and you may need
+to have multiport serial boards, if your computer doesn't have extra
+serial ports. In addition, a terminal emulator is also required, such as
+minicom. Refer to a manual of your operating system, for more
+information.
+
+As for GRUB, the instruction to set up a serial terminal is quite
+simple. Here is an example:
+
+@example
+@group
+grub> @kbd{serial --unit=0 --speed=9600}
+grub> @kbd{terminal_input serial; terminal_output serial}
+@end group
+@end example
+
+The command @command{serial} initializes the serial unit 0 with the
+speed 9600bps. The serial unit 0 is usually called @samp{COM1}, so, if
+you want to use COM2, you must specify @samp{--unit=1} instead. This
+command accepts many other options, so please refer to @ref{serial},
+for more details.
+
+The commands @command{terminal_input} (@pxref{terminal_input}) and
+@command{terminal_output} (@pxref{terminal_output}) choose which type of
+terminal you want to use. In the case above, the terminal will be a
+serial terminal, but you can also pass @code{console} to the command,
+as @samp{terminal_input serial console}. In this case, a terminal in which
+you press any key will be selected as a GRUB terminal. In the example above,
+note that you need to put both commands on the same command line, as you
+will lose the ability to type commands on the console after the first
+command.
+
+However, note that GRUB assumes that your terminal emulator is
+compatible with VT100 by default. This is true for most terminal
+emulators nowadays, but you should pass the option @option{--dumb} to
+the command if your terminal emulator is not VT100-compatible or
+implements few VT100 escape sequences. If you specify this option then
+GRUB provides you with an alternative menu interface, because the normal
+menu requires several fancy features of your terminal.
+
+
+@node Vendor power-on keys
+@chapter Using GRUB with vendor power-on keys
+
+Some laptop vendors provide an additional power-on button which boots another
+OS. GRUB supports such buttons with the @samp{GRUB_TIMEOUT_BUTTON},
+@samp{GRUB_DEFAULT_BUTTON}, @samp{GRUB_HIDDEN_TIMEOUT_BUTTON} and
+@samp{GRUB_BUTTON_CMOS_ADDRESS} variables in default/grub (@pxref{Simple
+configuration}). @samp{GRUB_TIMEOUT_BUTTON}, @samp{GRUB_DEFAULT_BUTTON} and
+@samp{GRUB_HIDDEN_TIMEOUT_BUTTON} are used instead of the corresponding
+variables without the @samp{_BUTTON} suffix when powered on using the special
+button. @samp{GRUB_BUTTON_CMOS_ADDRESS} is vendor-specific and partially
+model-specific. Values known to the GRUB team are:
+
+@table @key
+@item Dell XPS M1530
+85:3
+@item Asus EeePC 1005PE
+84:1 (unconfirmed)
+@end table
+
+To take full advantage of this function, install GRUB into the MBR
+(@pxref{Installing GRUB using grub-install}).
+
+If you have a laptop which has a similar feature and not in the above list
+could you figure your address and contribute?
+To discover the address do the following:
+@itemize
+@item boot normally
+@item
+@example
+sudo modprobe nvram
+sudo cat /dev/nvram | xxd > normal_button.txt
+@end example
+@item boot using vendor button
+@item
+@example
+sudo modprobe nvram
+sudo cat /dev/nvram | xxd > normal_vendor.txt
+@end example
+@end itemize
+
+Then compare these text files and find where a bit was toggled. E.g. in
+case of Dell XPS it was:
+@example
+byte 0x47: 20 --> 28
+@end example
+It's a bit number 3 as seen from following table:
+@multitable @columnfractions .2 .2
+@item 0 @tab 01
+@item 1 @tab 02
+@item 2 @tab 04
+@item 3 @tab 08
+@item 4 @tab 10
+@item 5 @tab 20
+@item 6 @tab 40
+@item 7 @tab 80
+@end multitable
+
+0x47 is decimal 71. Linux nvram implementation cuts first 14 bytes of
+CMOS. So the real byte address in CMOS is 71+14=85
+So complete address is 85:3
+
+@node Images
+@chapter GRUB image files
+
+@c FIXME: parts of this section are specific to PC BIOS right now.
+
+GRUB consists of several images: a variety of bootstrap images for starting
+GRUB in various ways, a kernel image, and a set of modules which are
+combined with the kernel image to form a core image. Here is a short
+overview of them.
+
+@table @file
+@item boot.img
+On PC BIOS systems, this image is the first part of GRUB to start. It is
+written to a master boot record (MBR) or to the boot sector of a partition.
+Because a PC boot sector is 512 bytes, the size of this image is exactly 512
+bytes.
+
+The sole function of @file{boot.img} is to read the first sector of the core
+image from a local disk and jump to it. Because of the size restriction,
+@file{boot.img} cannot understand any file system structure, so
+@command{grub-setup} hardcodes the location of the first sector of the core
+image into @file{boot.img} when installing GRUB.
+
+@item diskboot.img
+This image is used as the first sector of the core image when booting from a
+hard disk. It reads the rest of the core image into memory and starts the
+kernel. Since file system handling is not yet available, it encodes the
+location of the core image using a block list format.
+
+@item cdboot.img
+This image is used as the first sector of the core image when booting from a
+CD-ROM drive. It performs a similar function to @file{diskboot.img}.
+
+@item pxeboot.img
+This image is used as the start of the core image when booting from the
+network using PXE. @xref{Network}.
+
+@item lnxboot.img
+This image may be placed at the start of the core image in order to make
+GRUB look enough like a Linux kernel that it can be booted by LILO using an
+@samp{image=} section.
+
+@item kernel.img
+This image contains GRUB's basic run-time facilities: frameworks for device
+and file handling, environment variables, the rescue mode command-line
+parser, and so on. It is rarely used directly, but is built into all core
+images.
+
+@item core.img
+This is the core image of GRUB. It is built dynamically from the kernel
+image and an arbitrary list of modules by the @command{grub-mkimage}
+program. Usually, it contains enough modules to access @file{/boot/grub},
+and loads everything else (including menu handling, the ability to load
+target operating systems, and so on) from the file system at run-time. The
+modular design allows the core image to be kept small, since the areas of
+disk where it must be installed are often as small as 32KB.
+
+@xref{BIOS installation}, for details on where the core image can be
+installed on PC systems.
+
+@item *.mod
+Everything else in GRUB resides in dynamically loadable modules. These are
+often loaded automatically, or built into the core image if they are
+essential, but may also be loaded manually using the @command{insmod}
+command (@pxref{insmod}).
+@end table
+
+@heading For GRUB Legacy users
+
+GRUB 2 has a different design from GRUB Legacy, and so correspondences with
+the images it used cannot be exact. Nevertheless, GRUB Legacy users often
+ask questions in the terms they are familiar with, and so here is a brief
+guide to how GRUB 2's images relate to that.
+
+@table @file
+@item stage1
+Stage 1 from GRUB Legacy was very similar to @file{boot.img} in GRUB 2, and
+they serve the same function.
+
+@item *_stage1_5
+In GRUB Legacy, Stage 1.5's function was to include enough filesystem code
+to allow the much larger Stage 2 to be read from an ordinary filesystem. In
+this respect, its function was similar to @file{core.img} in GRUB 2.
+However, @file{core.img} is much more capable than Stage 1.5 was; since it
+offers a rescue shell, it is sometimes possible to recover manually in the
+event that it is unable to load any other modules, for example if partition
+numbers have changed. @file{core.img} is built in a more flexible way,
+allowing GRUB 2 to support reading modules from advanced disk types such as
+LVM and RAID.
+
+GRUB Legacy could run with only Stage 1 and Stage 2 in some limited
+configurations, while GRUB 2 requires @file{core.img} and cannot work
+without it.
+
+@item stage2
+GRUB 2 has no single Stage 2 image. Instead, it loads modules from
+@file{/boot/grub} at run-time.
+
+@item stage2_eltorito
+In GRUB 2, images for booting from CD-ROM drives are now constructed using
+@file{cdboot.img} and @file{core.img}, making sure that the core image
+contains the @samp{iso9660} module. It is usually best to use the
+@command{grub-mkrescue} program for this.
+
+@item nbgrub
+There is as yet no equivalent for @file{nbgrub} in GRUB 2; it was used by
+Etherboot and some other network boot loaders.
+
+@item pxegrub
+In GRUB 2, images for PXE network booting are now constructed using
+@file{pxeboot.img} and @file{core.img}, making sure that the core image
+contains the @samp{pxe} and @samp{pxecmd} modules. @xref{Network}.
+@end table
+
+
+@node Filesystem
+@chapter Filesystem syntax and semantics
+
+GRUB uses a special syntax for specifying disk drives which can be
+accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish
+between IDE, ESDI, SCSI, or others. You must know yourself which BIOS
+device is equivalent to which OS device. Normally, that will be clear if
+you see the files in a device or use the command @command{search}
+(@pxref{search}).
+
+@menu
+* Device syntax:: How to specify devices
+* File name syntax:: How to specify files
+* Block list syntax:: How to specify block lists
+@end menu
+
+
+@node Device syntax
+@section How to specify devices
+
+The device syntax is like this:
+
+@example
+@code{(@var{device}[,@var{part-num}][,@var{bsd-subpart-letter}])}
+@end example
+
+@samp{[]} means the parameter is optional. @var{device} should be
+either @samp{fd} or @samp{hd} followed by a digit, like @samp{fd0}.
+But you can also set @var{device} to a hexadecimal or a decimal number
+which is a BIOS drive number, so the following are equivalent:
+
+@example
+(hd0)
+(0x80)
+(128)
+@end example
+
+@var{part-num} represents the partition number of @var{device}, starting
+from one for primary partitions and from five for extended partitions,
+and @var{bsd-subpart-letter} represents the BSD disklabel subpartition,
+such as @samp{a} or @samp{e}.
+
+A shortcut for specifying BSD subpartitions is
+@code{(@var{device},@var{bsd-subpart-letter})}, in this case, GRUB
+searches for the first PC partition containing a BSD disklabel, then
+finds the subpartition @var{bsd-subpart-letter}. Here is an example:
+
+@example
+(hd0,a)
+@end example
+
+The syntax @samp{(hd0)} represents using the entire disk (or the
+MBR when installing GRUB), while the syntax @samp{(hd0,1)}
+represents using the first partition of the disk (or the boot sector
+of the partition when installing GRUB).
+
+If you enabled the network support, the special drive @samp{(pxe)} is
+also available. Before using the network drive, you must initialize the
+network. @xref{Network}, for more information.
+
+If you boot GRUB from a CD-ROM, @samp{(cd)} is available. @xref{Making
+a GRUB bootable CD-ROM}, for details.
+
+
+@node File name syntax
+@section How to specify files
+
+There are two ways to specify files, by @dfn{absolute file name} and by
+@dfn{block list}.
+
+An absolute file name resembles a Unix absolute file name, using
+@samp{/} for the directory separator (not @samp{\} as in DOS). One
+example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file
+@file{/boot/grub/grub.cfg} in the first partition of the first hard
+disk. If you omit the device name in an absolute file name, GRUB uses
+GRUB's @dfn{root device} implicitly. So if you set the root device to,
+say, @samp{(hd1,1)} by the command @samp{set root=(hd1,1)} (@pxref{set}),
+then @code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}.
+
+
+@node Block list syntax
+@section How to specify block lists
+
+A block list is used for specifying a file that doesn't appear in the
+filesystem, like a chainloader. The syntax is
+@code{[@var{offset}]+@var{length}[,[@var{offset}]+@var{length}]@dots{}}.
+Here is an example:
+
+@example
+@code{0+100,200+1,300+300}
+@end example
+
+This represents that GRUB should read blocks 0 through 99, block 200,
+and blocks 300 through 599. If you omit an offset, then GRUB assumes
+the offset is zero.
+
+Like the file name syntax (@pxref{File name syntax}), if a blocklist
+does not contain a device name, then GRUB uses GRUB's @dfn{root
+device}. So @code{(hd0,2)+1} is the same as @code{+1} when the root
+device is @samp{(hd0,2)}.
+
+
+@node Interface
+@chapter GRUB's user interface
+
+GRUB has both a simple menu interface for choosing preset entries from a
+configuration file, and a highly flexible command-line for performing
+any desired combination of boot commands.
+
+GRUB looks for its configuration file as soon as it is loaded. If one
+is found, then the full menu interface is activated using whatever
+entries were found in the file. If you choose the @dfn{command-line} menu
+option, or if the configuration file was not found, then GRUB drops to
+the command-line interface.
+
+@menu
+* Command-line interface:: The flexible command-line interface
+* Menu interface:: The simple menu interface
+* Menu entry editor:: Editing a menu entry
+@end menu
+
+
+@node Command-line interface
+@section The flexible command-line interface
+
+The command-line interface provides a prompt and after it an editable
+text area much like a command-line in Unix or DOS. Each command is
+immediately executed after it is entered@footnote{However, this
+behavior will be changed in the future version, in a user-invisible
+way.}. The commands (@pxref{Command-line and menu entry commands}) are a
+subset of those available in the configuration file, used with exactly
+the same syntax.
+
+Cursor movement and editing of the text on the line can be done via a
+subset of the functions available in the Bash shell:
+
+@table @key
+@item C-f
+@itemx PC right key
+Move forward one character.
+
+@item C-b
+@itemx PC left key
+Move back one character.
+
+@item C-a
+@itemx HOME
+Move to the start of the line.
+
+@item C-e
+@itemx END
+Move the the end of the line.
+
+@item C-d
+@itemx DEL
+Delete the character underneath the cursor.
+
+@item C-h
+@itemx BS
+Delete the character to the left of the cursor.
+
+@item C-k
+Kill the text from the current cursor position to the end of the line.
+
+@item C-u
+Kill backward from the cursor to the beginning of the line.
+
+@item C-y
+Yank the killed text back into the buffer at the cursor.
+
+@item C-p
+@itemx PC up key
+Move up through the history list.
+
+@item C-n
+@itemx PC down key
+Move down through the history list.
+@end table
+
+When typing commands interactively, if the cursor is within or before
+the first word in the command-line, pressing the @key{TAB} key (or
+@key{C-i}) will display a listing of the available commands, and if the
+cursor is after the first word, the @kbd{@key{TAB}} will provide a
+completion listing of disks, partitions, and file names depending on the
+context. Note that to obtain a list of drives, one must open a
+parenthesis, as @command{root (}.
+
+Note that you cannot use the completion functionality in the TFTP
+filesystem. This is because TFTP doesn't support file name listing for
+the security.
+
+
+@node Menu interface
+@section The simple menu interface
+
+The menu interface is quite easy to use. Its commands are both
+reasonably intuitive and described on screen.
+
+Basically, the menu interface provides a list of @dfn{boot entries} to
+the user to choose from. Use the arrow keys to select the entry of
+choice, then press @key{RET} to run it. An optional timeout is
+available to boot the default entry (the first one if not set), which is
+aborted by pressing any key.
+
+Commands are available to enter a bare command-line by pressing @key{c}
+(which operates exactly like the non-config-file version of GRUB, but
+allows one to return to the menu if desired by pressing @key{ESC}) or to
+edit any of the @dfn{boot entries} by pressing @key{e}.
+
+If you protect the menu interface with a password (@pxref{Security}),
+all you can do is choose an entry by pressing @key{RET}, or press
+@key{p} to enter the password.
+
+
+@node Menu entry editor
+@section Editing a menu entry
+
+The menu entry editor looks much like the main menu interface, but the
+lines in the menu are individual commands in the selected entry instead
+of entry names.
+
+If an @key{ESC} is pressed in the editor, it aborts all the changes made
+to the configuration entry and returns to the main menu interface.
+
+Each line in the menu entry can be edited freely, and you can add new lines
+by pressing @key{RET} at the end of a line. To boot the edited entry, press
+@key{Ctrl-x}.
+
+Although GRUB unfortunately does not support @dfn{undo}, you can do almost
+the same thing by just returning to the main menu using @key{ESC}.
+
+
+@node Environment
+@chapter GRUB environment variables
+
+GRUB supports environment variables which are rather like those offered by
+all Unix-like systems. Environment variables have a name, which is unique
+and is usually a short identifier, and a value, which is an arbitrary string
+of characters. They may be set (@pxref{set}), unset (@pxref{unset}), or
+looked up (@pxref{Shell-like scripting}) by name.
+
+A number of environment variables have special meanings to various parts of
+GRUB. Others may be used freely in GRUB configuration files.
+
+
+@menu
+* Special environment variables::
+* Environment block::
+@end menu
+
+
+@node Special environment variables
+@section Special environment variables
+
+These variables have special meaning to GRUB.
+
+@menu
+* biosnum::
+* chosen::
+* color_highlight::
+* color_normal::
+* debug::
+* default::
+* fallback::
+* gfxmode::
+* gfxpayload::
+* gfxterm_font::
+* icondir::
+* lang::
+* locale_dir::
+* menu_color_highlight::
+* menu_color_normal::
+* net_pxe_boot_file::
+* net_pxe_dhcp_server_name::
+* net_pxe_domain::
+* net_pxe_extensionspath::
+* net_pxe_hostname::
+* net_pxe_ip::
+* net_pxe_mac::
+* net_pxe_rootpath::
+* pager::
+* prefix::
+* pxe_blksize::
+* pxe_default_gateway::
+* pxe_default_server::
+* root::
+* superusers::
+* theme::
+* timeout::
+@end menu
+
+
+@node biosnum
+@subsection biosnum
+
+When chain-loading another boot loader (@pxref{Chain-loading}), GRUB may
+need to know what BIOS drive number corresponds to the root device
+(@pxref{root}) so that it can set up registers properly. If the
+@var{biosnum} variable is set, it overrides GRUB's own means of guessing
+this.
+
+For an alternative approach which also changes BIOS drive mappings for the
+chain-loaded system, @pxref{drivemap}.
+
+
+@node chosen
+@subsection chosen
+
+When executing a menu entry, GRUB sets the @var{chosen} variable to the
+title of the entry being executed.
+
+If the menu entry is in one or more submenus, then @var{chosen} is set to
+the titles of each of the submenus starting from the top level followed by
+the title of the menu entry itself, separated by @samp{>}.
+
+
+@node color_highlight
+@subsection color_highlight
+
+This variable contains the ``highlight'' foreground and background terminal
+colors, separated by a slash (@samp{/}). Setting this variable changes
+those colors. For the available color names, @pxref{color_normal}.
+
+The default is @samp{black/white}.
+
+
+@node color_normal
+@subsection color_normal
+
+This variable contains the ``normal'' foreground and background terminal
+colors, separated by a slash (@samp{/}). Setting this variable changes
+those colors. Each color must be a name from the following list:
+
+@itemize @bullet
+@item black
+@item blue
+@item green
+@item cyan
+@item red
+@item magenta
+@item brown
+@item light-gray
+@item dark-gray
+@item light-blue
+@item light-green
+@item light-cyan
+@item light-red
+@item light-magenta
+@item yellow
+@item white
+@end itemize
+
+The default is @samp{white/black}.
+
+
+@node debug
+@subsection debug
+
+This variable may be set to enable debugging output from various components
+of GRUB. The value is a list of debug facility names separated by
+whitespace or @samp{,}, or @samp{all} to enable all available debugging
+output.
+
+
+@node default
+@subsection default
+
+If this variable is set, it identifies a menu entry that should be selected
+by default, possibly after a timeout (@pxref{timeout}). The entry may be
+identified by number or by title.
+
+If the entry is in a submenu, then it must be identified using the titles of
+each of the submenus starting from the top level followed by the number or
+title of the menu entry itself, separated by @samp{>}. For example, take
+the following menu structure:
+
+@example
+Submenu 1
+ Menu Entry 1
+ Menu Entry 2
+Submenu 2
+ Submenu 3
+ Menu Entry 3
+ Menu Entry 4
+ Menu Entry 5
+@end example
+
+``Menu Entry 3'' would then be identified as
+@samp{Submenu 2>Submenu 3>Menu Entry 3}.
+
+This variable is often set by @samp{GRUB_DEFAULT} (@pxref{Simple
+configuration}), @command{grub-set-default}, or @command{grub-reboot}.
+
+
+@node fallback
+@subsection fallback
+
+If this variable is set, it identifies a menu entry that should be selected
+if the default menu entry fails to boot. Entries are identified in the same
+way as for @samp{default} (@pxref{default}).
+
+
+@node gfxmode
+@subsection gfxmode
+
+If this variable is set, it sets the resolution used on the @samp{gfxterm}
+graphical terminal. Note that you can only use modes which your graphics
+card supports via VESA BIOS Extensions (VBE), so for example native LCD
+panel resolutions may not be available. The default is @samp{auto}, which
+selects a platform-specific default that should look reasonable.
+
+The resolution may be specified as a sequence of one or more modes,
+separated by commas (@samp{,}) or semicolons (@samp{;}); each will be tried
+in turn until one is found. Each mode should be either @samp{auto},
+@samp{@var{width}x@var{height}}, or
+@samp{@var{width}x@var{height}x@var{depth}}.
+
+
+@node gfxpayload
+@subsection gfxpayload
+
+If this variable is set, it controls the video mode in which the Linux
+kernel starts up, replacing the @samp{vga=} boot option (@pxref{linux}). It
+may be set to @samp{text} to force the Linux kernel to boot in normal text
+mode, @samp{keep} to preserve the graphics mode set using @samp{gfxmode}, or
+any of the permitted values for @samp{gfxmode} to set a particular graphics
+mode (@pxref{gfxmode}).
+
+Depending on your kernel, your distribution, your graphics card, and the
+phase of the moon, note that using this option may cause GNU/Linux to suffer
+from various display problems, particularly during the early part of the
+boot sequence. If you have problems, set this variable to @samp{text} and
+GRUB will tell Linux to boot in normal text mode.
+
+The default is platform-specific. On platforms with a native text mode
+(such as PC BIOS platforms), the default is @samp{text}. Otherwise the
+default may be @samp{auto} or a specific video mode.
+
+This variable is often set by @samp{GRUB_GFXPAYLOAD_LINUX} (@pxref{Simple
+configuration}).
+
+
+@node gfxterm_font
+@subsection gfxterm_font
+
+If this variable is set, it names a font to use for text on the
+@samp{gfxterm} graphical terminal. Otherwise, @samp{gfxterm} may use any
+available font.
+
+
+@node icondir
+@subsection icondir
+
+If this variable is set, it names a directory in which the GRUB graphical
+menu should look for icons after looking in the theme's @samp{icons}
+directory. @xref{Theme file format}.
+
+
+@node lang
+@subsection lang
+
+If this variable is set, it names the language code that the
+@command{gettext} command (@pxref{gettext}) uses to translate strings. For
+example, French would be named as @samp{fr}, and Simplified Chinese as
+@samp{zh_CN}.
+
+@command{grub-mkconfig} (@pxref{Simple configuration}) will try to set a
+reasonable default for this variable based on the system locale.
+
+
+@node locale_dir
+@subsection locale_dir
+
+If this variable is set, it names the directory where translation files may
+be found (@pxref{gettext}), usually @file{/boot/grub/locale}. Otherwise,
+internationalization is disabled.
+
+@command{grub-mkconfig} (@pxref{Simple configuration}) will set a reasonable
+default for this variable if internationalization is needed and any
+translation files are available.
+
+
+@node menu_color_highlight
+@subsection menu_color_highlight
+
+This variable contains the foreground and background colors to be used for
+the highlighted menu entry, separated by a slash (@samp{/}). Setting this
+variable changes those colors. For the available color names,
+@pxref{color_normal}.
+
+The default is the value of @samp{color_highlight}
+(@pxref{color_highlight}).
+
+
+@node menu_color_normal
+@subsection menu_color_normal
+
+This variable contains the foreground and background colors to be used for
+non-highlighted menu entries, separated by a slash (@samp{/}). Setting this
+variable changes those colors. For the available color names,
+@pxref{color_normal}.
+
+The default is the value of @samp{color_normal} (@pxref{color_normal}).
+
+
+@node net_pxe_boot_file
+@subsection net_pxe_boot_file
+
+@xref{Network}.
+
+
+@node net_pxe_dhcp_server_name
+@subsection net_pxe_dhcp_server_name
+
+@xref{Network}.
+
+
+@node net_pxe_domain
+@subsection net_pxe_domain
+
+@xref{Network}.
+
+
+@node net_pxe_extensionspath
+@subsection net_pxe_extensionspath
+
+@xref{Network}.
+
+
+@node net_pxe_hostname
+@subsection net_pxe_hostname
+
+@xref{Network}.
+
+
+@node net_pxe_ip
+@subsection net_pxe_ip
+
+@xref{Network}.
+
+
+@node net_pxe_mac
+@subsection net_pxe_mac
+
+@xref{Network}.
+
+
+@node net_pxe_rootpath
+@subsection net_pxe_rootpath
+
+@xref{Network}.
+
+
+@node pager
+@subsection pager
+
+If set to @samp{1}, pause output after each screenful and wait for keyboard
+input. The default is not to pause output.
+
+
+@node prefix
+@subsection prefix
+
+The location of the @samp{/boot/grub} directory as an absolute file name
+(@pxref{File name syntax}). This is normally set by GRUB at startup based
+on information provided by @command{grub-install}. GRUB modules are
+dynamically loaded from this directory, so it must be set correctly in order
+for many parts of GRUB to work.
+
+
+@node pxe_blksize
+@subsection pxe_blksize
+
+@xref{Network}.
+
+
+@node pxe_default_gateway
+@subsection pxe_default_gateway
+
+@xref{Network}.
+
+
+@node pxe_default_server
+@subsection pxe_default_server
+
+@xref{Network}.
+
+
+@node root
+@subsection root
+
+The root device name (@pxref{Device syntax}). Any file names that do not
+specify an explicit device name are read from this device. The default is
+normally set by GRUB at startup based on the value of @samp{prefix}
+(@pxref{prefix}).
+
+For example, if GRUB was installed to the first partition of the first hard
+disk, then @samp{prefix} might be set to @samp{(hd0,msdos1)/boot/grub} and
+@samp{root} to @samp{hd0,msdos1}.
+
+
+@node superusers
+@subsection superusers
+
+This variable may be set to a list of superuser names to enable
+authentication support. @xref{Security}.
+
+
+@node theme
+@subsection theme
+
+This variable may be set to a directory containing a GRUB graphical menu
+theme. @xref{Theme file format}.
+
+This variable is often set by @samp{GRUB_THEME} (@pxref{Simple
+configuration}).
+
+
+@node timeout
+@subsection timeout
+
+If this variable is set, it specifies the time in seconds to wait for
+keyboard input before booting the default menu entry. A timeout of @samp{0}
+means to boot the default entry immediately without displaying the menu; a
+timeout of @samp{-1} (or unset) means to wait indefinitely.
+
+This variable is often set by @samp{GRUB_TIMEOUT} or
+@samp{GRUB_HIDDEN_TIMEOUT} (@pxref{Simple configuration}).
+
+
+@node Environment block
+@section The GRUB environment block
+
+It is often useful to be able to remember a small amount of information from
+one boot to the next. For example, you might want to set the default menu
+entry based on what was selected the last time. GRUB deliberately does not
+implement support for writing files in order to minimise the possibility of
+the boot loader being responsible for file system corruption, so a GRUB
+configuration file cannot just create a file in the ordinary way. However,
+GRUB provides an ``environment block'' which can be used to save a small
+amount of state.
+
+The environment block is a preallocated 1024-byte file, which normally lives
+in @file{/boot/grub/grubenv} (although you should not assume this). At boot
+time, the @command{load_env} command (@pxref{load_env}) loads environment
+variables from it, and the @command{save_env} (@pxref{save_env}) command
+saves environment variables to it. From a running system, the
+@command{grub-editenv} utility can be used to edit the environment block.
+
+For safety reasons, this storage is only available when installed on a plain
+disk (no LVM or RAID), using a non-checksumming filesystem (no ZFS), and
+using BIOS or EFI functions (no ATA, USB or IEEE1275).
+
+@command{grub-mkconfig} uses this facility to implement
+@samp{GRUB_SAVEDEFAULT} (@pxref{Simple configuration}).
+
+
+@node Commands
+@chapter The list of available commands
+
+In this chapter, we list all commands that are available in GRUB.
+
+Commands belong to different groups. A few can only be used in
+the global section of the configuration file (or ``menu''); most
+of them can be entered on the command-line and can be used either
+anywhere in the menu or specifically in the menu entries.
+
+In rescue mode, only the @command{insmod} (@pxref{insmod}), @command{ls}
+(@pxref{ls}), @command{set} (@pxref{set}), and @command{unset}
+(@pxref{unset}) commands are normally available. If you end up in rescue
+mode and do not know what to do, then @pxref{GRUB only offers a rescue
+shell}.
+
+@menu
+* Menu-specific commands::
+* General commands::
+* Command-line and menu entry commands::
+@end menu
+
+
+@node Menu-specific commands
+@section The list of commands for the menu only
+
+The semantics used in parsing the configuration file are the following:
+
+@itemize @bullet
+@item
+The files @emph{must} be in plain-text format.
+
+@item
+@samp{#} at the beginning of a line in a configuration file means it is
+only a comment.
+
+@item
+Options are separated by spaces.
+
+@item
+All numbers can be either decimal or hexadecimal. A hexadecimal number
+must be preceded by @samp{0x}, and is case-insensitive.
+@end itemize
+
+These commands can only be used in the menu:
+
+@menu
+* menuentry:: Start a menu entry
+* submenu:: Group menu entries
+@end menu
+
+
+@node menuentry
+@subsection menuentry
+
+@deffn Command menuentry @var{title} @
+ [@option{--class=class} @dots{}] [@option{--users=users}] @
+ [@option{--hotkey=key}] @
+ @{ @var{command}; @dots{} @}
+This defines a GRUB menu entry named @var{title}. When this entry is
+selected from the menu, GRUB will set the @var{chosen} environment variable
+to @var{title}, execute the list of commands given within braces, and if the
+last command in the list returned successfully and a kernel was loaded it
+will execute the @command{boot} command.
+
+The @option{--class} option may be used any number of times to group menu
+entries into classes. Menu themes may display different classes using
+different styles.
+
+The @option{--users} option grants specific users access to specific menu
+entries. @xref{Security}.
+
+The @option{--hotkey} option associates a hotkey with a menu entry.
+@var{key} may be a single letter, or one of the aliases @samp{backspace},
+@samp{tab}, or @samp{delete}.
+@end deffn
+
+
+@node submenu
+@subsection submenu
+
+@deffn Command submenu @var{title} @
+ [@option{--class=class} @dots{}] [@option{--users=users}] @
+ [@option{--hotkey=key}] @
+ @{ @var{menu entries} @dots{} @}
+This defines a submenu. An entry called @var{title} will be added to the
+menu; when that entry is selected, a new menu will be displayed showing all
+the entries within this submenu.
+
+All options are the same as in the @command{menuentry} command
+(@pxref{menuentry}).
+@end deffn
+
+
+@node General commands
+@section The list of general commands
+
+Commands usable anywhere in the menu and in the command-line.
+
+@menu
+* serial:: Set up a serial device
+* terminal_input:: Manage input terminals
+* terminal_output:: Manage output terminals
+* terminfo:: Define terminal type
+@end menu
+
+
+@node serial
+@subsection serial
+
+@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}]
+Initialize a serial device. @var{unit} is a number in the range 0-3
+specifying which serial port to use; default is 0, which corresponds to
+the port often called COM1. @var{port} is the I/O port where the UART
+is to be found; if specified it takes precedence over @var{unit}.
+@var{speed} is the transmission speed; default is 9600. @var{word} and
+@var{stop} are the number of data bits and stop bits. Data bits must
+be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data
+bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd},
+@samp{even} and defaults to @samp{no}.
+
+The serial port is not used as a communication channel unless the
+@command{terminal_input} or @command{terminal_output} command is used
+(@pxref{terminal_input}, @pxref{terminal_output}).
+
+See also @ref{Serial terminal}.
+@end deffn
+
+
+@node terminal_input
+@subsection terminal_input
+
+@deffn Command terminal_input [@option{--append}|@option{--remove}] @
+ [terminal1] [terminal2] @dots{}
+List or select an input terminal.
+
+With no arguments, list the active and available input terminals.
+
+With @option{--append}, add the named terminals to the list of active input
+terminals; any of these may be used to provide input to GRUB.
+
+With @option{--remove}, remove the named terminals from the active list.
+
+With no options but a list of terminal names, make only the listed terminal
+names active.
+@end deffn
+
+
+@node terminal_output
+@subsection terminal_output
+
+@deffn Command terminal_output [@option{--append}|@option{--remove}] @
+ [terminal1] [terminal2] @dots{}
+List or select an output terminal.
+
+With no arguments, list the active and available output terminals.
+
+With @option{--append}, add the named terminals to the list of active output
+terminals; all of these will receive output from GRUB.
+
+With @option{--remove}, remove the named terminals from the active list.
+
+With no options but a list of terminal names, make only the listed terminal
+names active.
+@end deffn
+
+
+@node terminfo
+@subsection terminfo
+
+@deffn Command terminfo [-a|-u|-v] [term]
+Define the capabilities of your terminal by giving the name of an entry in
+the terminfo database, which should correspond roughly to a @samp{TERM}
+environment variable in Unix.
+
+The currently available terminal types are @samp{vt100}, @samp{vt100-color},
+@samp{ieee1275}, and @samp{dumb}. If you need other terminal types, please
+contact us to discuss the best way to include support for these in GRUB.
+
+The @option{-a} (@option{--ascii}), @option{-u} (@option{--utf8}), and
+@option{-v} (@option{--visual-utf8}) options control how non-ASCII text is
+displayed. @option{-a} specifies an ASCII-only terminal; @option{-u}
+specifies logically-ordered UTF-8; and @option{-v} specifies
+"visually-ordered UTF-8" (in other words, arranged such that a terminal
+emulator without bidirectional text support will display right-to-left text
+in the proper order; this is not really proper UTF-8, but a workaround).
+
+If no option or terminal type is specified, the current terminal type is
+printed.
+@end deffn
+
+
+@node Command-line and menu entry commands
+@section The list of command-line and menu entry commands
+
+These commands are usable in the command-line and in menu entries. If
+you forget a command, you can run the command @command{help}
+(@pxref{help}).
+
+@menu
+* acpi:: Load ACPI tables
+* badram:: Filter out bad regions of RAM
+* blocklist:: Print a block list
+* boot:: Start up your operating system
+* cat:: Show the contents of a file
+* chainloader:: Chain-load another boot loader
+* cmp:: Compare two files
+* configfile:: Load a configuration file
+* cpuid:: Check for CPU features
+* crc:: Calculate CRC32 checksums
+* date:: Display or set current date and time
+* drivemap:: Map a drive to another
+* echo:: Display a line of text
+* export:: Export an environment variable
+* false:: Do nothing, unsuccessfully
+* gettext:: Translate a string
+* gptsync:: Fill an MBR based on GPT entries
+* halt:: Shut down your computer
+* help:: Show help messages
+* initrd:: Load a Linux initrd
+* initrd16:: Load a Linux initrd (16-bit mode)
+* insmod:: Insert a module
+* keystatus:: Check key modifier status
+* linux:: Load a Linux kernel
+* linux16:: Load a Linux kernel (16-bit mode)
+* list_env:: List variables in environment block
+* load_env:: Load variables from environment block
+* loopback:: Make a device from a filesystem image
+* ls:: List devices or files
+* normal:: Enter normal mode
+* normal_exit:: Exit from normal mode
+* parttool:: Modify partition table entries
+* password:: Set a clear-text password
+* password_pbkdf2:: Set a hashed password
+* play:: Play a tune
+* pxe_unload:: Unload the PXE environment
+* read:: Read user input
+* reboot:: Reboot your computer
+* save_env:: Save variables to environment block
+* search:: Search devices by file, label, or UUID
+* sendkey:: Emulate keystrokes
+* set:: Set an environment variable
+* true:: Do nothing, successfully
+* unset:: Unset an environment variable
+* uppermem:: Set the upper memory size
+@end menu
+
+
+@node acpi
+@subsection acpi
+
+@deffn Command acpi [@option{-1}|@option{-2}] @
+ [@option{--exclude=table1,@dots{}}|@option{--load-only=table1,@dots{}}] @
+ [@option{--oemid=id}] [@option{--oemtable=table}] @
+ [@option{--oemtablerev=rev}] [@option{--oemtablecreator=creator}] @
+ [@option{--oemtablecreatorrev=rev}] [@option{--no-ebda}] @
+ filename @dots{}
+Modern BIOS systems normally implement the Advanced Configuration and Power
+Interface (ACPI), and define various tables that describe the interface
+between an ACPI-compliant operating system and the firmware. In some cases,
+the tables provided by default only work well with certain operating
+systems, and it may be necessary to replace some of them.
+
+Normally, this command will replace the Root System Description Pointer
+(RSDP) in the Extended BIOS Data Area to point to the new tables. If the
+@option{--no-ebda} option is used, the new tables will be known only to
+GRUB, but may be used by GRUB's EFI emulation.
+@end deffn
+
+@node badram
+@subsection badram
+
+@deffn Command badram addr,mask[,addr,mask...]
+Filter out bad RAM.
+@end deffn
+
+This command notifies the memory manager that specified regions of
+RAM ought to be filtered out (usually, because they're damaged). This
+remains in effect after a payload kernel has been loaded by GRUB, as
+long as the loaded kernel obtains its memory map from GRUB. Kernels that
+support this include Linux, GNU Mach, the kernel of FreeBSD and Multiboot
+kernels in general.
+
+Syntax is the same as provided by the @uref{http://www.memtest.org/,
+Memtest86+ utility}: a list of address/mask pairs. Given a page-aligned
+address and a base address / mask pair, if all the bits of the page-aligned
+address that are enabled by the mask match with the base address, it means
+this page is to be filtered. This syntax makes it easy to represent patterns
+that are often result of memory damage, due to physical distribution of memory
+cells.
+
+@node blocklist
+@subsection blocklist
+
+@deffn Command blocklist file
+Print a block list (@pxref{Block list syntax}) for @var{file}.
+@end deffn
+
+
+@node boot
+@subsection boot
+
+@deffn Command boot
+Boot the OS or chain-loader which has been loaded. Only necessary if
+running the fully interactive command-line (it is implicit at the end of
+a menu entry).
+@end deffn
+
+
+@node cat
+@subsection cat
+
+@deffn Command cat [@option{--dos}] file
+Display the contents of the file @var{file}. This command may be useful
+to remind you of your OS's root partition:
+
+@example
+grub> @kbd{cat /etc/fstab}
+@end example
+
+If the @option{--dos} option is used, then carriage return / new line pairs
+will be displayed as a simple new line. Otherwise, the carriage return will
+be displayed as a control character (@samp{<d>}) to make it easier to see
+when boot problems are caused by a file formatted using DOS-style line
+endings.
+@end deffn
+
+
+@node chainloader
+@subsection chainloader
+
+@deffn Command chainloader [@option{--force}] file
+Load @var{file} as a chain-loader. Like any other file loaded by the
+filesystem code, it can use the blocklist notation (@pxref{Block list
+syntax}) to grab the first sector of the current partition with @samp{+1}.
+If you specify the option @option{--force}, then load @var{file} forcibly,
+whether it has a correct signature or not. This is required when you want to
+load a defective boot loader, such as SCO UnixWare 7.1.
+@end deffn
+
+
+@node cmp
+@subsection cmp
+
+@deffn Command cmp file1 file2
+Compare the file @var{file1} with the file @var{file2}. If they differ
+in size, print the sizes like this:
+
+@example
+Differ in size: 0x1234 [foo], 0x4321 [bar]
+@end example
+
+If the sizes are equal but the bytes at an offset differ, then print the
+bytes like this:
+
+@example
+Differ at the offset 777: 0xbe [foo], 0xef [bar]
+@end example
+
+If they are completely identical, nothing will be printed.
+@end deffn
+
+
+@node configfile
+@subsection configfile
+
+@deffn Command configfile file
+Load @var{file} as a configuration file. If @var{file} defines any menu
+entries, then show a menu containing them immediately.
+@end deffn
+
+
+@node cpuid
+@subsection cpuid
+
+@deffn Command cpuid [-l]
+Check for CPU features. This command is only available on x86 systems.
+
+With the @option{-l} option, return true if the CPU supports long mode
+(64-bit).
+
+If invoked without options, this command currently behaves as if it had been
+invoked with @option{-l}. This may change in the future.
+@end deffn
+
+
+@node crc
+@subsection crc
+
+@deffn Command crc file
+Display the CRC32 checksum of @var{file}.
+@end deffn
+
+
+@node date
+@subsection date
+
+@deffn Command date [[year-]month-day] [hour:minute[:second]]
+With no arguments, print the current date and time.
+
+Otherwise, take the current date and time, change any elements specified as
+arguments, and set the result as the new date and time. For example, `date
+01-01' will set the current month and day to January 1, but leave the year,
+hour, minute, and second unchanged.
+@end deffn
+
+
+@node drivemap
+@subsection drivemap
+
+@deffn Command drivemap @option{-l}|@option{-r}|[@option{-s}] @
+ from_drive to_drive
+Without options, map the drive @var{from_drive} to the drive @var{to_drive}.
+This is necessary when you chain-load some operating systems, such as DOS,
+if such an OS resides at a non-first drive. For convenience, any partition
+suffix on the drive is ignored, so you can safely use @verb{'${root}'} as a
+drive specification.
+
+With the @option{-s} option, perform the reverse mapping as well, swapping
+the two drives.
+
+With the @option{-l} option, list the current mappings.
+
+With the @option{-r} option, reset all mappings to the default values.
+
+For example:
+
+@example
+drivemap -s (hd0) (hd1)
+@end example
+@end deffn
+
+
+@node echo
+@subsection echo
+
+@deffn Command echo [@option{-n}] [@option{-e}] string @dots{}
+Display the requested text and, unless the @option{-n} option is used, a
+trailing new line. If there is more than one string, they are separated by
+spaces in the output. As usual in GRUB commands, variables may be
+substituted using @samp{$@{var@}}.
+
+The @option{-e} option enables interpretation of backslash escapes. The
+following sequences are recognised:
+
+@table @code
+@item \\
+backslash
+
+@item \a
+alert (BEL)
+
+@item \c
+suppress trailing new line
+
+@item \f
+form feed
+
+@item \n
+new line
+
+@item \r
+carriage return
+
+@item \t
+horizontal tab
+
+@item \v
+vertical tab
+@end table
+
+When interpreting backslash escapes, backslash followed by any other
+character will print that character.
+@end deffn
+
+
+@node export
+@subsection export
+
+@deffn Command export envvar
+Export the environment variable @var{envvar}. Exported variables are visible
+to subsidiary configuration files loaded using @command{configfile}.
+@end deffn
+
+
+@node false
+@subsection false
+
+@deffn Command false
+Do nothing, unsuccessfully. This is mainly useful in control constructs
+such as @code{if} and @code{while} (@pxref{Shell-like scripting}).
+@end deffn
+
+
+@node gettext
+@subsection gettext
+
+@deffn Command gettext string
+Translate @var{string} into the current language.
+
+The current language code is stored in the @samp{lang} variable in GRUB's
+environment (@pxref{lang}). Translation files in MO format are read from
+@samp{locale_dir} (@pxref{locale_dir}), usually @file{/boot/grub/locale}.
+@end deffn
+
+
+@node gptsync
+@subsection gptsync
+
+@deffn Command gptsync device [partition[+/-[type]]] @dots{}
+Disks using the GUID Partition Table (GPT) also have a legacy Master Boot
+Record (MBR) partition table for compatibility with the BIOS and with older
+operating systems. The legacy MBR can only represent a limited subset of
+GPT partition entries.
+
+This command populates the legacy MBR with the specified @var{partition}
+entries on @var{device}. Up to three partitions may be used.
+
+@var{type} is an MBR partition type code; prefix with @samp{0x} if you want
+to enter this in hexadecimal. The separator between @var{partition} and
+@var{type} may be @samp{+} to make the partition active, or @samp{-} to make
+it inactive; only one partition may be active. If both the separator and
+type are omitted, then the partition will be inactive.
+@end deffn
+
+
+@node halt
+@subsection halt
+
+@deffn Command halt @option{--no-apm}
+The command halts the computer. If the @option{--no-apm} option
+is specified, no APM BIOS call is performed. Otherwise, the computer
+is shut down using APM.
+@end deffn
+
+
+@node help
+@subsection help
+
+@deffn Command help [pattern @dots{}]
+Display helpful information about builtin commands. If you do not
+specify @var{pattern}, this command shows short descriptions of all
+available commands.
+
+If you specify any @var{patterns}, it displays longer information
+about each of the commands whose names begin with those @var{patterns}.
+@end deffn
+
+
+@node initrd
+@subsection initrd
+
+@deffn Command initrd file
+Load an initial ramdisk for a Linux kernel image, and set the appropriate
+parameters in the Linux setup area in memory. This may only be used after
+the @command{linux} command (@pxref{linux}) has been run. See also
+@ref{GNU/Linux}.
+@end deffn
+
+
+@node initrd16
+@subsection initrd16
+
+@deffn Command initrd16 file
+Load an initial ramdisk for a Linux kernel image to be booted in 16-bit
+mode, and set the appropriate parameters in the Linux setup area in memory.
+This may only be used after the @command{linux16} command (@pxref{linux16})
+has been run. See also @ref{GNU/Linux}.
+
+This command is only available on x86 systems.
+@end deffn
+
+
+@node insmod
+@subsection insmod
+
+@deffn Command insmod module
+Insert the dynamic GRUB module called @var{module}.
+@end deffn
+
+
+@node keystatus
+@subsection keystatus
+
+@deffn Command keystatus [@option{--shift}] [@option{--ctrl}] [@option{--alt}]
+Return true if the Shift, Control, or Alt modifier keys are held down, as
+requested by options. This is useful in scripting, to allow some user
+control over behaviour without having to wait for a keypress.
+
+Checking key modifier status is only supported on some platforms. If invoked
+without any options, the @command{keystatus} command returns true if and
+only if checking key modifier status is supported.
+@end deffn
+
+
+@node linux
+@subsection linux
+
+@deffn Command linux file @dots{}
+Load a Linux kernel image from @var{file}. The rest of the line is passed
+verbatim as the @dfn{kernel command-line}. Any initrd must be reloaded
+after using this command (@pxref{initrd}).
+
+On x86 systems, the kernel will be booted using the 32-bit boot protocol.
+Note that this means that the @samp{vga=} boot option will not work; if you
+want to set a special video mode, you will need to use GRUB commands such as
+@samp{set gfxpayload=1024x768} or @samp{set gfxpayload=keep} (to keep the
+same mode as used in GRUB) instead. GRUB can automatically detect some uses
+of @samp{vga=} and translate them to appropriate settings of
+@samp{gfxpayload}. The @command{linux16} command (@pxref{linux16}) avoids
+this restriction.
+@end deffn
+
+
+@node linux16
+@subsection linux16
+
+@deffn Command linux16 file @dots{}
+Load a Linux kernel image from @var{file} in 16-bit mode. The rest of the
+line is passed verbatim as the @dfn{kernel command-line}. Any initrd must
+be reloaded after using this command (@pxref{initrd16}).
+
+The kernel will be booted using the traditional 16-bit boot protocol. As
+well as bypassing problems with @samp{vga=} described in @ref{linux}, this
+permits booting some other programs that implement the Linux boot protocol
+for the sake of convenience.
+
+This command is only available on x86 systems.
+@end deffn
+
+
+@node list_env
+@subsection list_env
+
+@deffn Command list_env [@option{-f} file]
+List all variables in the environment block file. @xref{Environment block}.
+
+The @option{-f} option overrides the default location of the environment
+block.
+@end deffn
+
+
+@node load_env
+@subsection load_env
+
+@deffn Command load_env [@option{-f} file]
+Load all variables from the environment block file into the environment.
+@xref{Environment block}.
+
+The @option{-f} option overrides the default location of the environment
+block.
+@end deffn
+
+
+@node loopback
+@subsection loopback
+
+@deffn Command loopback [@option{-d}] device file
+Make the device named @var{device} correspond to the contents of the
+filesystem image in @var{file}. For example:
+
+@example
+loopback loop0 /path/to/image
+ls (loop0)/
+@end example
+
+With the @option{-d} option, delete a device previously created using this
+command.
+@end deffn
+
+
+@node ls
+@subsection ls
+
+@deffn Command ls [arg @dots{}]
+List devices or files.
+
+With no arguments, print all devices known to GRUB.
+
+If the argument is a device name enclosed in parentheses (@pxref{Device
+syntax}), then list all files at the root directory of that device.
+
+If the argument is a directory given as an absolute file name (@pxref{File
+name syntax}), then list the contents of that directory.
+@end deffn
+
+
+@node normal
+@subsection normal
+
+@deffn Command normal [file]
+Enter normal mode and display the GRUB menu.
+
+In normal mode, commands, filesystem modules, and cryptography modules are
+automatically loaded, and the full GRUB script parser is available. Other
+modules may be explicitly loaded using @command{insmod} (@pxref{insmod}).
+
+If a @var{file} is given, then commands will be read from that file.
+Otherwise, they will be read from @file{$prefix/grub.cfg} if it exists.
+
+@command{normal} may be called from within normal mode, creating a nested
+environment. It is more usual to use @command{configfile}
+(@pxref{configfile}) for this.
+@end deffn
+
+
+@node normal_exit
+@subsection normal_exit
+
+@deffn Command normal_exit
+Exit normal mode (@pxref{normal}). If this instance of normal mode was not
+nested within another one, then return to rescue mode.
+@end deffn
+
+
+@node parttool
+@subsection parttool
+
+@deffn Command parttool partition commands
+Make various modifications to partition table entries.
+
+Each @var{command} is either a boolean option, in which case it must be
+followed with @samp{+} or @samp{-} (with no intervening space) to enable or
+disable that option, or else it takes a value in the form
+@samp{@var{command}=@var{value}}.
+
+Currently, @command{parttool} is only useful on DOS partition tables (also
+known as Master Boot Record, or MBR). On these partition tables, the
+following commands are available:
+
+@table @asis
+@item @samp{boot} (boolean)
+When enabled, this makes the selected partition be the active (bootable)
+partition on its disk, clearing the active flag on all other partitions.
+This command is limited to @emph{primary} partitions.
+
+@item @samp{type} (value)
+Change the type of an existing partition. The value must be a number in the
+range 0-0xFF (prefix with @samp{0x} to enter it in hexadecimal).
+
+@item @samp{hidden} (boolean)
+When enabled, this hides the selected partition by setting the @dfn{hidden}
+bit in its partition type code; when disabled, unhides the selected
+partition by clearing this bit. This is useful only when booting DOS or
+Wwindows and multiple primary FAT partitions exist in one disk. See also
+@ref{DOS/Windows}.
+@end table
+@end deffn
+
+
+@node password
+@subsection password
+
+@deffn Command password user clear-password
+Define a user named @var{user} with password @var{clear-password}.
+@xref{Security}.
+@end deffn
+
+
+@node password_pbkdf2
+@subsection password_pbkdf2
+
+@deffn Command password_pbkdf2 user hashed-password
+Define a user named @var{user} with password hash @var{hashed-password}.
+Use @command{grub-mkpasswd-pbkdf2} (@pxref{Invoking grub-mkpasswd-pbkdf2})
+to generate password hashes. @xref{Security}.
+@end deffn
+
+
+@node play
+@subsection play
+
+@deffn Command play file | tempo [pitch1 duration1] [pitch2 duration2] ...
+Plays a tune
+
+If the argument is a file name (@pxref{File name syntax}), play the tune
+recorded in it. The file format is first the tempo as an unsigned 32bit
+little-endian number, then pairs of unsigned 16bit little-endian numbers for
+pitch and duration pairs.
+
+If the arguments are a series of numbers, play the inline tune.
+
+The tempo is the base for all note durations. 60 gives a 1-second base, 120
+gives a half-second base, etc. Pitches are Hz. Set pitch to 0 to produce
+a rest.
+@end deffn
+
+
+@node pxe_unload
+@subsection pxe_unload
+
+@deffn Command pxe_unload
+Unload the PXE environment (@pxref{Network}).
+
+This command is only available on PC BIOS systems.
+@end deffn
+
+
+@node read
+@subsection read
+
+@deffn Command read [var]
+Read a line of input from the user. If an environment variable @var{var} is
+given, set that environment variable to the line of input that was read,
+with no terminating newline.
+@end deffn
+
+
+@node reboot
+@subsection reboot
+
+@deffn Command reboot
+Reboot the computer.
+@end deffn
+
+
+@node save_env
+@subsection save_env
+
+@deffn Command save_env [@option{-f} file] var @dots{}
+Save the named variables from the environment to the environment block file.
+@xref{Environment block}.
+
+The @option{-f} option overrides the default location of the environment
+block.
+@end deffn
+
+
+@node search
+@subsection search
+
+@deffn Command search @
+ [@option{--file}|@option{--label}|@option{--fs-uuid}] @
+ [@option{--set} [var]] [@option{--no-floppy}] name
+Search devices by file (@option{-f}, @option{--file}), filesystem label
+(@option{-l}, @option{--label}), or filesystem UUID (@option{-u},
+@option{--fs-uuid}).
+
+If the @option{--set} option is used, the first device found is set as the
+value of environment variable @var{var}. The default variable is
+@samp{root}.
+
+The @option{--no-floppy} option prevents searching floppy devices, which can
+be slow.
+
+The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid}
+commands are aliases for @samp{search --file}, @samp{search --label}, and
+@samp{search --fs-uuid} respectively.
+@end deffn
+
+
+@node sendkey
+@subsection sendkey
+
+@deffn Command sendkey @
+ [@option{--num}|@option{--caps}|@option{--scroll}|@option{--insert}|@
+@option{--pause}|@option{--left-shift}|@option{--right-shift}|@
+@option{--sysrq}|@option{--numkey}|@option{--capskey}|@option{--scrollkey}|@
+@option{--insertkey}|@option{--left-alt}|@option{--right-alt}|@
+@option{--left-ctrl}|@option{--right-ctrl} @
+ @samp{on}|@samp{off}]@dots{} @
+ [@option{no-led}] @
+ keystroke
+Insert keystrokes into the keyboard buffer when booting. Sometimes an
+operating system or chainloaded boot loader requires particular keys to be
+pressed: for example, one might need to press a particular key to enter
+"safe mode", or when chainloading another boot loader one might send
+keystrokes to it to navigate its menu.
+
+You may provide up to 16 keystrokes (the length of the BIOS keyboard
+buffer). Keystroke names may be upper-case or lower-case letters, digits,
+or taken from the following table:
+
+@c Please keep this table in the same order as in
+@c commands/i386/pc/sendkey.c, for ease of maintenance.
+@c Exception: The function and numeric keys are sorted, for aesthetics.
+
+@multitable @columnfractions .4 .5
+@headitem Name @tab Key
+@item escape @tab Escape
+@item exclam @tab !
+@item at @tab @@
+@item numbersign @tab #
+@item dollar @tab $
+@item percent @tab %
+@item caret @tab ^
+@item ampersand @tab &
+@item asterisk @tab *
+@item parenleft @tab (
+@item parenright @tab )
+@item minus @tab -
+@item underscore @tab _
+@item equal @tab =
+@item plus @tab +
+@item backspace @tab Backspace
+@item tab @tab Tab
+@item bracketleft @tab [
+@item braceleft @tab @{
+@item bracketright @tab ]
+@item braceright @tab @}
+@item enter @tab Enter
+@item control @tab press and release Control
+@item semicolon @tab ;
+@item colon @tab :
+@item quote @tab '
+@item doublequote @tab "
+@item backquote @tab `
+@item tilde @tab ~
+@item shift @tab press and release left Shift
+@item backslash @tab \
+@item bar @tab |
+@item comma @tab ,
+@item less @tab <
+@item period @tab .
+@item greater @tab >
+@item slash @tab /
+@item question @tab ?
+@item rshift @tab press and release right Shift
+@item alt @tab press and release Alt
+@item space @tab space bar
+@item capslock @tab Caps Lock
+@item F1 @tab F1
+@item F2 @tab F2
+@item F3 @tab F3
+@item F4 @tab F4
+@item F5 @tab F5
+@item F6 @tab F6
+@item F7 @tab F7
+@item F8 @tab F8
+@item F9 @tab F9
+@item F10 @tab F10
+@item F11 @tab F11
+@item F12 @tab F12
+@item num1 @tab 1 (numeric keypad)
+@item num2 @tab 2 (numeric keypad)
+@item num3 @tab 3 (numeric keypad)
+@item num4 @tab 4 (numeric keypad)
+@item num5 @tab 5 (numeric keypad)
+@item num6 @tab 6 (numeric keypad)
+@item num7 @tab 7 (numeric keypad)
+@item num8 @tab 8 (numeric keypad)
+@item num9 @tab 9 (numeric keypad)
+@item num0 @tab 0 (numeric keypad)
+@item numperiod @tab . (numeric keypad)
+@item numend @tab End (numeric keypad)
+@item numdown @tab Down (numeric keypad)
+@item numpgdown @tab Page Down (numeric keypad)
+@item numleft @tab Left (numeric keypad)
+@item numcenter @tab 5 with Num Lock inactive (numeric keypad)
+@item numright @tab Right (numeric keypad)
+@item numhome @tab Home (numeric keypad)
+@item numup @tab Up (numeric keypad)
+@item numpgup @tab Page Up (numeric keypad)
+@item numinsert @tab Insert (numeric keypad)
+@item numdelete @tab Delete (numeric keypad)
+@item numasterisk @tab * (numeric keypad)
+@item numminus @tab - (numeric keypad)
+@item numplus @tab + (numeric keypad)
+@item numslash @tab / (numeric keypad)
+@item numenter @tab Enter (numeric keypad)
+@item delete @tab Delete
+@item insert @tab Insert
+@item home @tab Home
+@item end @tab End
+@item pgdown @tab Page Down
+@item pgup @tab Page Up
+@item down @tab Down
+@item up @tab Up
+@item left @tab Left
+@item right @tab Right
+@end multitable
+
+As well as keystrokes, the @command{sendkey} command takes various options
+that affect the BIOS keyboard status flags. These options take an @samp{on}
+or @samp{off} parameter, specifying that the corresponding status flag be
+set or unset; omitting the option for a given status flag will leave that
+flag at its initial state at boot. The @option{--num}, @option{--caps},
+@option{--scroll}, and @option{--insert} options emulate setting the
+corresponding mode, while the @option{--numkey}, @option{--capskey},
+@option{--scrollkey}, and @option{--insertkey} options emulate pressing and
+holding the corresponding key. The other status flag options are
+self-explanatory.
+
+If the @option{--no-led} option is given, the status flag options will have
+no effect on keyboard LEDs.
+
+If the @command{sendkey} command is given multiple times, then only the last
+invocation has any effect.
+
+Since @command{sendkey} manipulates the BIOS keyboard buffer, it may cause
+hangs, reboots, or other misbehaviour on some systems. If the operating
+system or boot loader that runs after GRUB uses its own keyboard driver
+rather than the BIOS keyboard functions, then @command{sendkey} will have no
+effect.
+
+This command is only available on PC BIOS systems.
+@end deffn
+
+
+@node set
+@subsection set
+
+@deffn Command set [envvar=value]
+Set the environment variable @var{envvar} to @var{value}. If invoked with no
+arguments, print all environment variables with their values.
+@end deffn
+
+
+@node true
+@subsection true
+
+@deffn Command true
+Do nothing, successfully. This is mainly useful in control constructs such
+as @code{if} and @code{while} (@pxref{Shell-like scripting}).
+@end deffn
+
+
+@node unset
+@subsection unset
+
+@deffn Command unset envvar
+Unset the environment variable @var{envvar}.
+@end deffn
+
+
+@node uppermem
+@subsection uppermem
+
+This command is not yet implemented for GRUB 2, although it is planned.
+
+
+@node Security
+@chapter Authentication and authorisation
+
+By default, the boot loader interface is accessible to anyone with physical
+access to the console: anyone can select and edit any menu entry, and anyone
+can get direct access to a GRUB shell prompt. For most systems, this is
+reasonable since anyone with direct physical access has a variety of other
+ways to gain full access, and requiring authentication at the boot loader
+level would only serve to make it difficult to recover broken systems.
+
+However, in some environments, such as kiosks, it may be appropriate to lock
+down the boot loader to require authentication before performing certain
+operations.
+
+The @samp{password} (@pxref{password}) and @samp{password_pbkdf2}
+(@pxref{password_pbkdf2}) commands can be used to define users, each of
+which has an associated password. @samp{password} sets the password in
+plain text, requiring @file{grub.cfg} to be secure; @samp{password_pbkdf2}
+sets the password hashed using the Password-Based Key Derivation Function
+(RFC 2898), requiring the use of @command{grub-mkpasswd-pbkdf2}
+(@pxref{Invoking grub-mkpasswd-pbkdf2}) to generate password hashes.
+
+In order to enable authentication support, the @samp{superusers} environment
+variable must be set to a list of usernames, separated by any of spaces,
+commas, semicolons, pipes, or ampersands. Superusers are permitted to use
+the GRUB command line, edit menu entries, and execute any menu entry. If
+@samp{superusers} is set, then use of the command line is automatically
+restricted to superusers.
+
+Other users may be given access to specific menu entries by giving a list of
+usernames (as above) using the @option{--users} option to the
+@samp{menuentry} command (@pxref{menuentry}). If the @option{--users}
+option is not used for a menu entry, then that entry is unrestricted.
+
+Putting this together, a typical @file{grub.cfg} fragment might look like
+this:
+
+@example
+@group
+set superusers="root"
+password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring
+password user1 insecure
+
+menuentry "May be run by any user" @{
+ set root=(hd0,1)
+ linux /vmlinuz
+@}
+
+menuentry "Superusers only" --users "" @{
+ set root=(hd0,1)
+ linux /vmlinuz single
+@}
+
+menuentry "May be run by user1 or a superuser" --users user1 @{
+ set root=(hd0,2)
+ chainloader +1
+@}
+@end group
+@end example
+
+The @command{grub-mkconfig} program does not yet have built-in support for
+generating configuration files with authentication. You can use
+@file{/etc/grub.d/40_custom} to add simple superuser authentication, by
+adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2}
+commands.
+
+
+@node Supported kernels
+@chapter Supported boot targets
+
+X86 support is summarised in the following table. ``Yes'' means that the kernel works on the given platform, ``crashes'' means an early kernel crash which we hope will be fixed by concerned kernel developers. ``no'' means GRUB doesn't load the given kernel on a given platform. ``headless'' means that the kernel works but lacks console drivers (you can still use serial or network console). In case of ``no'' and ``crashes'' the reason is given in footnote.
+@multitable @columnfractions .50 .22 .22
+@item @tab BIOS @tab Coreboot
+@item BIOS chainloading @tab yes @tab no (1)
+@item NTLDR @tab yes @tab no (1)
+@item FreeBSD bootloader @tab yes @tab crashes (1)
+@item 32-bit kFreeBSD @tab yes @tab crashes (2,6)
+@item 64-bit kFreeBSD @tab yes @tab crashes (2,6)
+@item 32-bit kNetBSD @tab yes @tab crashes (1)
+@item 64-bit kNetBSD @tab yes @tab crashes (2)
+@item 32-bit kOpenBSD @tab yes @tab yes
+@item 64-bit kOpenBSD @tab yes @tab yes
+@item Multiboot @tab yes @tab yes
+@item Multiboot2 @tab yes @tab yes
+@item 32-bit Linux (legacy protocol) @tab yes @tab no (1)
+@item 64-bit Linux (legacy protocol) @tab yes @tab no (1)
+@item 32-bit Linux (modern protocol) @tab yes @tab yes
+@item 64-bit Linux (modern protocol) @tab yes @tab yes
+@item 32-bit XNU @tab yes @tab ?
+@item 64-bit XNU @tab yes @tab ?
+@item 32-bit EFI chainloader @tab no (3) @tab no (3)
+@item 64-bit EFI chainloader @tab no (3) @tab no (3)
+@item Appleloader @tab no (3) @tab no (3)
+@end multitable
+
+@multitable @columnfractions .50 .22 .22
+@item @tab Multiboot @tab Qemu
+@item BIOS chainloading @tab no (1) @tab no (1)
+@item NTLDR @tab no (1) @tab no (1)
+@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
+@item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6)
+@item 64-bit kFreeBSD @tab crashes (6) @tab crashes (6)
+@item 32-bit kNetBSD @tab crashes (1) @tab crashes (1)
+@item 64-bit kNetBSD @tab yes @tab yes
+@item 32-bit kOpenBSD @tab yes @tab yes
+@item 64-bit kOpenBSD @tab yes @tab yes
+@item Multiboot @tab yes @tab yes
+@item Multiboot2 @tab yes @tab yes
+@item 32-bit Linux (legacy protocol) @tab no (1) @tab no (1)
+@item 64-bit Linux (legacy protocol) @tab no (1) @tab no (1)
+@item 32-bit Linux (modern protocol) @tab yes @tab yes
+@item 64-bit Linux (modern protocol) @tab yes @tab yes
+@item 32-bit XNU @tab ? @tab ?
+@item 64-bit XNU @tab ? @tab ?
+@item 32-bit EFI chainloader @tab no (3) @tab no (3)
+@item 64-bit EFI chainloader @tab no (3) @tab no (3)
+@item Appleloader @tab no (3) @tab no (3)
+@end multitable
+
+@multitable @columnfractions .50 .22 .22
+@item @tab 32-bit EFI @tab 64-bit EFI
+@item BIOS chainloading @tab no (1) @tab no (1)
+@item NTLDR @tab no (1) @tab no (1)
+@item FreeBSD bootloader @tab crashes (1) @tab crashes (1)
+@item 32-bit kFreeBSD @tab headless @tab headless
+@item 64-bit kFreeBSD @tab headless @tab headless
+@item 32-bit kNetBSD @tab crashes (1) @tab crashes (1)
+@item 64-bit kNetBSD @tab yes @tab yes
+@item 32-bit kOpenBSD @tab headless @tab headless
+@item 64-bit kOpenBSD @tab headless @tab headless
+@item Multiboot @tab yes @tab yes
+@item Multiboot2 @tab yes @tab yes
+@item 32-bit Linux (legacy protocol) @tab no (1) @tab no (1)
+@item 64-bit Linux (legacy protocol) @tab no (1) @tab no (1)
+@item 32-bit Linux (modern protocol) @tab yes @tab yes
+@item 64-bit Linux (modern protocol) @tab yes @tab yes
+@item 32-bit XNU @tab yes @tab yes
+@item 64-bit XNU @tab yes (5) @tab yes
+@item 32-bit EFI chainloader @tab yes @tab no (4)
+@item 64-bit EFI chainloader @tab no (4) @tab yes
+@item Appleloader @tab yes @tab yes
+@end multitable
+
+@multitable @columnfractions .50 .22 .22
+@item @tab IEEE1275
+@item BIOS chainloading @tab no (1)
+@item NTLDR @tab no (1)
+@item FreeBSD bootloader @tab crashes (1)
+@item 32-bit kFreeBSD @tab crashes (6)
+@item 64-bit kFreeBSD @tab crashes (6)
+@item 32-bit kNetBSD @tab crashes (1)
+@item 64-bit kNetBSD @tab ?
+@item 32-bit kOpenBSD @tab ?
+@item 64-bit kOpenBSD @tab ?
+@item Multiboot @tab ?
+@item Multiboot2 @tab ?
+@item 32-bit Linux (legacy protocol) @tab no (1)
+@item 64-bit Linux (legacy protocol) @tab no (1)
+@item 32-bit Linux (modern protocol) @tab ?
+@item 64-bit Linux (modern protocol) @tab ?
+@item 32-bit XNU @tab ?
+@item 64-bit XNU @tab ?
+@item 32-bit EFI chainloader @tab no (3)
+@item 64-bit EFI chainloader @tab no (3)
+@item Appleloader @tab no (3)
+@end multitable
+
+@enumerate
+@item Requires BIOS
+@item Crashes because the memory at 0x0-0x1000 isn't available
+@item EFI only
+@item 32-bit and 64-bit EFI have different structures and work in different CPU modes so it's not possible to chainload 32-bit bootloader on 64-bit platform and vice-versa
+@item Some modules may need to be disabled
+@item Requires ACPI
+@end enumerate
+
+PowerPC and Sparc ports support only Linux. MIPS port supports Linux and multiboot2.
+
+@chapter Boot tests
+
+As you have seen in previous chapter the support matrix is pretty big and some of the configurations are only rarely used. To ensure the quality bootchecks are available for all x86 targets except EFI chainloader, Appleloader and XNU. All x86 platforms have bootcheck facility except ieee1275. Multiboot, multiboot2, BIOS chainloader, ntldr and freebsd-bootloader boot targets are tested only with a fake kernel images. Only Linux is tested among the payloads using Linux protocols.
+
+Following variables must be defined:
+
+@multitable @columnfractions .30 .65
+@item GRUB_PAYLOADS_DIR @tab directory containing the required kernels
+@item GRUB_CBFSTOOL @tab cbfstoll from Coreboot package (for coreboot platform only)
+@item GRUB_COREBOOT_ROM @tab empty Coreboot ROM
+@item GRUB_QEMU_OPTS @tab additional options to be supplied to QEMU
+@end multitable
+
+Required files are:
+
+@multitable @columnfractions .40 .55
+@item kfreebsd_env.i386 @tab 32-bit kFreeBSD device hints
+@item kfreebsd.i386 @tab 32-bit FreeBSD kernel image
+@item kfreebsd.x86_64, kfreebsd_env.x86_64 @tab same from 64-bit kFreeBSD
+@item knetbsd.i386 @tab 32-bit NetBSD kernel image
+@item knetbsd.miniroot.i386 @tab 32-bit kNetBSD miniroot.kmod.
+@item knetbsd.x86_64, knetbsd.miniroot.x86_64 @tab same from 64-bit kNetBSD
+@item kopenbsd.i386 @tab 32-bit OpenBSD kernel bsd.rd image
+@item kopenbsd.x86_64 @tab same from 64-bit kOpenBSD
+@item linux.i386 @tab 32-bit Linux
+@item linux.x86_64 @tab 64-bit Linux
+@end multitable
+
+@node Troubleshooting
+@chapter Error messages produced by GRUB
+
+@menu
+* GRUB only offers a rescue shell::
+@end menu
+
+
+@node GRUB only offers a rescue shell
+@section GRUB only offers a rescue shell
+
+GRUB's normal start-up procedure involves setting the @samp{prefix}
+environment variable to a value set in the core image by
+@command{grub-install}, setting the @samp{root} variable to match, loading
+the @samp{normal} module from the prefix, and running the @samp{normal}
+command (@pxref{normal}). This command is responsible for reading
+@file{/boot/grub/grub.cfg}, running the menu, and doing all the useful
+things GRUB is supposed to do.
+
+If, instead, you only get a rescue shell, this usually means that GRUB
+failed to load the @samp{normal} module for some reason. It may be possible
+to work around this temporarily: for instance, if the reason for the failure
+is that @samp{prefix} is wrong (perhaps it refers to the wrong device, or
+perhaps the path to @file{/boot/grub} was not correctly made relative to the
+device), then you can correct this and enter normal mode manually:
+
+@example
+@group
+# Inspect the current prefix (and other preset variables):
+set
+# Find out which devices are available:
+ls
+# Set to the correct value, which might be something like this:
+set prefix=(hd0,1)/grub
+set root=(hd0,1)
+insmod normal
+normal
+@end group
+@end example
+
+However, any problem that leaves you in the rescue shell probably means that
+GRUB was not correctly installed. It may be more useful to try to reinstall
+it properly using @kbd{grub-install @var{device}} (@pxref{Invoking
+grub-install}). When doing this, there are a few things to remember:
+
+@itemize @bullet{}
+@item
+Drive ordering in your operating system may not be the same as the boot
+drive ordering used by your firmware. Do not assume that your first hard
+drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from.
+@file{device.map} (@pxref{Device map}) can be used to override this, but it
+is usually better to use UUIDs or file system labels and avoid depending on
+drive ordering entirely.
+
+@item
+At least on BIOS systems, if you tell @command{grub-install} to install GRUB
+to a partition but GRUB has already been installed in the master boot
+record, then the GRUB installation in the partition will be ignored.
+
+@item
+If possible, it is generally best to avoid installing GRUB to a partition
+(unless it is a special partition for the use of GRUB alone, such as the
+BIOS Boot Partition used on GPT). Doing this means that GRUB may stop being
+able to read its core image due to a file system moving blocks around, such
+as while defragmenting, running checks, or even during normal operation.
+Installing to the whole disk device is normally more robust.
+
+@item
+Check that GRUB actually knows how to read from the device and file system
+containing @file{/boot/grub}. It will not be able to read from encrypted
+devices, nor from file systems for which support has not yet been added to
+GRUB.
+@end itemize
+
+
+@node Invoking grub-install
+@chapter Invoking grub-install
+
+The program @command{grub-install} installs GRUB on your drive using
+@command{grub-mkimage} and (on some platforms) @command{grub-setup}. You
+must specify the device name on which you want to install GRUB, like this:
+
+@example
+grub-install @var{install_device}
+@end example
+
+The device name @var{install_device} is an OS device name or a GRUB
+device name.
+
+@command{grub-install} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item --boot-directory=@var{dir}
+Install GRUB images under the directory @file{@var{dir}/grub/}
+This option is useful when you want to install GRUB into a
+separate partition or a removable disk.
+If this option is not specified then it defaults to @file{/boot}, so
+
+@example
+@kbd{grub-install /dev/sda}
+@end example
+
+is equivalent to
+
+@example
+@kbd{grub-install --boot-directory=/boot/ /dev/sda}
+@end example
+
+Here is an example in which you have a separate @dfn{boot} partition which is
+mounted on
+@file{/mnt/boot}:
+
+@example
+@kbd{grub-install --boot-directory=/mnt/boot /dev/sdb}
+@end example
+
+@item --recheck
+Recheck the device map, even if @file{/boot/grub/device.map} already
+exists. You should use this option whenever you add/remove a disk
+into/from your computer.
+@end table
+
+
+@node Invoking grub-mkconfig
+@chapter Invoking grub-mkconfig
+
+The program @command{grub-mkconfig} generates a configuration file for GRUB
+(@pxref{Simple configuration}).
+
+@example
+grub-mkconfig -o /boot/grub/grub.cfg
+@end example
+
+@command{grub-mkconfig} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item -o @var{file}
+@itemx --output=@var{file}
+Send the generated configuration file to @var{file}. The default is to send
+it to standard output.
+@end table
+
+
+@node Invoking grub-mkpasswd-pbkdf2
+@chapter Invoking grub-mkpasswd-pbkdf2
+
+The program @command{grub-mkpasswd-pbkdf2} generates password hashes for
+GRUB (@pxref{Security}).
+
+@example
+grub-mkpasswd-pbkdf2
+@end example
+
+@command{grub-mkpasswd-pbkdf2} accepts the following options:
+
+@table @option
+@item -c @var{number}
+@itemx --iteration-count=@var{number}
+Number of iterations of the underlying pseudo-random function. Defaults to
+10000.
+
+@item -l @var{number}
+@itemx --buflen=@var{number}
+Length of the generated hash. Defaults to 64.
+
+@item -s @var{number}
+@itemx --salt=@var{number}
+Length of the salt. Defaults to 64.
+@end table
+
+
+@node Invoking grub-mkrescue
+@chapter Invoking grub-mkrescue
+
+The program @command{grub-mkrescue} generates a bootable GRUB rescue image
+(@pxref{Making a GRUB bootable CD-ROM}).
+
+@example
+grub-mkrescue -o grub.iso
+@end example
+
+All arguments not explicitly listed as @command{grub-mkrescue} options are
+passed on directly to @command{xorriso} in @command{mkisofs} emulation mode.
+Options passed to @command{xorriso} will normally be interpreted as
+@command{mkisofs} options; if the option @samp{--} is used, then anything
+after that will be interpreted as native @command{xorriso} options.
+
+Non-option arguments specify additional source directories. This is
+commonly used to add extra files to the image:
+
+@example
+mkdir -p disk/boot/grub
+@r{(add extra files to @file{disk/boot/grub})}
+grub-mkrescue -o grub.iso disk
+@end example
+
+@command{grub-mkrescue} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item -o @var{file}
+@itemx --output=@var{file}
+Save output in @var{file}. This "option" is required.
+
+@item --modules=@var{modules}
+Pre-load the named GRUB modules in the image. Multiple entries in
+@var{modules} should be separated by whitespace (so you will probably need
+to quote this for your shell).
+
+@item --rom-directory=@var{dir}
+If generating images for the QEMU or Coreboot platforms, copy the resulting
+@file{qemu.img} or @file{coreboot.elf} files respectively to the @var{dir}
+directory as well as including them in the image.
+
+@item --xorriso=@var{file}
+Use @var{file} as the @command{xorriso} program, rather than the built-in
+default.
+
+@item --grub-mkimage=@var{file}
+Use @var{file} as the @command{grub-mkimage} program, rather than the
+built-in default.
+@end table
+
+
+@node Obtaining and Building GRUB
+@appendix How to obtain and build GRUB
+
+@quotation
+@strong{Caution:} GRUB requires binutils-2.9.1.0.23 or later because the
+GNU assembler has been changed so that it can produce real 16bits
+machine code between 2.9.1 and 2.9.1.0.x. See
+@uref{http://sources.redhat.com/binutils/}, to obtain information on
+how to get the latest version.
+@end quotation
+
+GRUB is available from the GNU alpha archive site
+@uref{ftp://alpha.gnu.org/gnu/grub} or any of its mirrors. The file
+will be named grub-version.tar.gz. The current version is
+@value{VERSION}, so the file you should grab is:
+
+@uref{ftp://alpha.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz}
+
+To unbundle GRUB use the instruction:
+
+@example
+@kbd{zcat grub-@value{VERSION}.tar.gz | tar xvf -}
+@end example
+
+which will create a directory called @file{grub-@value{VERSION}} with
+all the sources. You can look at the file @file{INSTALL} for detailed
+instructions on how to build and install GRUB, but you should be able to
+just do:
+
+@example
+@group
+@kbd{cd grub-@value{VERSION}}
+@kbd{./configure}
+@kbd{make install}
+@end group
+@end example
+
+Also, the latest version is available using Bazaar. See
+@uref{http://www.gnu.org/software/grub/grub-download.en.html} for more
+information.
+
+@node Reporting bugs
+@appendix Reporting bugs
+
+These are the guideline for how to report bugs. Take a look at this
+list below before you submit bugs:
+
+@enumerate
+@item
+Before getting unsettled, read this manual through and through. Also,
+see the @uref{http://www.gnu.org/software/grub/grub-faq.html, GNU GRUB FAQ}.
+
+@item
+Always mention the information on your GRUB. The version number and the
+configuration are quite important. If you build it yourself, write the
+options specified to the configure script and your operating system,
+including the versions of gcc and binutils.
+
+@item
+If you have trouble with the installation, inform us of how you
+installed GRUB. Don't omit error messages, if any. Just @samp{GRUB hangs
+up when it boots} is not enough.
+
+The information on your hardware is also essential. These are especially
+important: the geometries and the partition tables of your hard disk
+drives and your BIOS.
+
+@item
+If GRUB cannot boot your operating system, write down
+@emph{everything} you see on the screen. Don't paraphrase them, like
+@samp{The foo OS crashes with GRUB, even though it can boot with the
+bar boot loader just fine}. Mention the commands you executed, the
+messages printed by them, and information on your operating system
+including the version number.
+
+@item
+Explain what you wanted to do. It is very useful to know your purpose
+and your wish, and how GRUB didn't satisfy you.
+
+@item
+If you can investigate the problem yourself, please do. That will give
+you and us much more information on the problem. Attaching a patch is
+even better.
+
+When you attach a patch, make the patch in unified diff format, and
+write ChangeLog entries. But, even when you make a patch, don't forget
+to explain the problem, so that we can understand what your patch is
+for.
+
+@item
+Write down anything that you think might be related. Please understand
+that we often need to reproduce the same problem you encountered in our
+environment. So your information should be sufficient for us to do the
+same thing---Don't forget that we cannot see your computer directly. If
+you are not sure whether to state a fact or leave it out, state it!
+Reporting too many things is much better than omitting something
+important.
+@end enumerate
+
+If you follow the guideline above, submit a report to the
+@uref{http://savannah.gnu.org/bugs/?group=grub, Bug Tracking System}.
+Alternatively, you can submit a report via electronic mail to
+@email{bug-grub@@gnu.org}, but we strongly recommend that you use the
+Bug Tracking System, because e-mail can be passed over easily.
+
+Once we get your report, we will try to fix the bugs.
+
+
+@node Future
+@appendix Where GRUB will go
+
+GRUB 2 is now quite stable and used in many production systems. We are
+currently working towards a 2.0 release.
+
+If you are interested in the development of GRUB 2, take a look at
+@uref{http://www.gnu.org/software/grub/grub.html, the homepage}.
+
+
+
+
+
+@node Copying This Manual
+@appendix Copying This Manual
+
+@menu
+* GNU Free Documentation License:: License for copying this manual.
+@end menu
+
+@include fdl.texi
+
+
+@node Index
+@unnumbered Index
+
+@c Currently, we use only the Concept Index.
+@printindex cp
+
+
+@bye
+
+Some notes:
+
+ This is an attempt to make a manual for GRUB 2. The contents are
+ copied from the GRUB manual in GRUB Legacy, so they are not always
+ appropriate yet for GRUB 2.
diff --git a/docs/man/grub-bin2h.h2m b/docs/man/grub-bin2h.h2m
new file mode 100644
index 0000000..ef463f3
--- /dev/null
+++ b/docs/man/grub-bin2h.h2m
@@ -0,0 +1,2 @@
+[NAME]
+grub-bin2h \- convert a binary file to a C header
diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m
new file mode 100644
index 0000000..3859d3d
--- /dev/null
+++ b/docs/man/grub-editenv.h2m
@@ -0,0 +1,5 @@
+[NAME]
+grub-editenv \- edit GRUB environment block
+[SEE ALSO]
+.BR grub-reboot (8),
+.BR grub-set-default (8)
diff --git a/docs/man/grub-emu.h2m b/docs/man/grub-emu.h2m
new file mode 100644
index 0000000..ef1c000
--- /dev/null
+++ b/docs/man/grub-emu.h2m
@@ -0,0 +1,6 @@
+[NAME]
+grub-emu \- GRUB emulator
+[SEE ALSO]
+If you are trying to install GRUB, then you should use
+.BR grub-install (8)
+rather than this program.
diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m
new file mode 100644
index 0000000..9676b15
--- /dev/null
+++ b/docs/man/grub-fstest.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-fstest \- debug tool for GRUB filesystem drivers
+[SEE ALSO]
+.BR grub-probe (8)
diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m
new file mode 100644
index 0000000..2de371a
--- /dev/null
+++ b/docs/man/grub-install.h2m
@@ -0,0 +1,7 @@
+[NAME]
+grub-install \- install GRUB to a device
+[SEE ALSO]
+.BR grub-mkconfig (8),
+.BR grub-mkimage (1),
+.BR grub-setup (8),
+.BR grub-mkrescue (1)
diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m
new file mode 100644
index 0000000..d79aaee
--- /dev/null
+++ b/docs/man/grub-macho2img.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-macho2img \- convert Mach-O to raw image
+[SEE ALSO]
+.BR grub-mkimage (1)
diff --git a/docs/man/grub-menulst2cfg.h2m b/docs/man/grub-menulst2cfg.h2m
new file mode 100644
index 0000000..c2e0055
--- /dev/null
+++ b/docs/man/grub-menulst2cfg.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-menulst2cfg \- transform legacy menu.lst into grub.cfg
+[SEE ALSO]
+.BR grub-mkconfig (8)
diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m
new file mode 100644
index 0000000..9b42f81
--- /dev/null
+++ b/docs/man/grub-mkconfig.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mkconfig \- generate a GRUB configuration file
+[SEE ALSO]
+.BR grub-install (8)
diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m
new file mode 100644
index 0000000..3ef8e97
--- /dev/null
+++ b/docs/man/grub-mkdevicemap.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mkdevicemap \- generate a GRUB device map file automatically
+[SEE ALSO]
+.BR grub-install (8)
diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m
new file mode 100644
index 0000000..d46fe60
--- /dev/null
+++ b/docs/man/grub-mkfont.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mkfont \- make GRUB font files
+[SEE ALSO]
+.BR grub-mkconfig (8)
diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m
new file mode 100644
index 0000000..ca08b0c
--- /dev/null
+++ b/docs/man/grub-mkimage.h2m
@@ -0,0 +1,7 @@
+[NAME]
+grub-mkimage \- make a bootable image of GRUB
+[SEE ALSO]
+.BR grub-install (8),
+.BR grub-setup (8),
+.BR grub-mkrescue (1),
+.BR grub-mknetdir (8)
diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m
new file mode 100644
index 0000000..cda6f36
--- /dev/null
+++ b/docs/man/grub-mklayout.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mklayout \- generate a GRUB keyboard layout file
+[SEE ALSO]
+.BR grub-mkconfig (8)
diff --git a/docs/man/grub-mknetdir.h2m b/docs/man/grub-mknetdir.h2m
new file mode 100644
index 0000000..a2ef13e
--- /dev/null
+++ b/docs/man/grub-mknetdir.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mknetdir \- prepare a GRUB netboot directory.
+[SEE ALSO]
+.BR grub-mkimage (1)
diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m
new file mode 100644
index 0000000..4d202f3
--- /dev/null
+++ b/docs/man/grub-mkpasswd-pbkdf2.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB
+[SEE ALSO]
+.BR grub-mkconfig (8)
diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m
new file mode 100644
index 0000000..d01f396
--- /dev/null
+++ b/docs/man/grub-mkrelpath.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mkrelpath \- make a system path relative to its root
+[SEE ALSO]
+.BR grub-probe (8)
diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m
new file mode 100644
index 0000000..a427f02
--- /dev/null
+++ b/docs/man/grub-mkrescue.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-mkrescue \- make a GRUB rescue image
+[SEE ALSO]
+.BR grub-mkimage (1)
diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m
new file mode 100644
index 0000000..74b43ee
--- /dev/null
+++ b/docs/man/grub-ofpathname.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-ofpathname \- find OpenBOOT path for a device
+[SEE ALSO]
+.BR grub-probe (8)
diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m
new file mode 100644
index 0000000..7ca29bd
--- /dev/null
+++ b/docs/man/grub-pe2elf.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-pe2elf \- convert PE image to ELF
+[SEE ALSO]
+.BR grub-mkimage (1)
diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m
new file mode 100644
index 0000000..6e1ffdc
--- /dev/null
+++ b/docs/man/grub-probe.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-probe \- probe device information for GRUB
+[SEE ALSO]
+.BR grub-fstest (1)
diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m
new file mode 100644
index 0000000..e4acace
--- /dev/null
+++ b/docs/man/grub-reboot.h2m
@@ -0,0 +1,5 @@
+[NAME]
+grub-reboot \- set the default boot entry for GRUB, for the next boot only
+[SEE ALSO]
+.BR grub-set-default (8),
+.BR grub-editenv (1)
diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m
new file mode 100644
index 0000000..3653682
--- /dev/null
+++ b/docs/man/grub-script-check.h2m
@@ -0,0 +1,4 @@
+[NAME]
+grub-script-check \- check grub.cfg for syntax errors
+[SEE ALSO]
+.BR grub-mkconfig (8)
diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m
new file mode 100644
index 0000000..7945001
--- /dev/null
+++ b/docs/man/grub-set-default.h2m
@@ -0,0 +1,5 @@
+[NAME]
+grub-set-default \- set the saved default boot entry for GRUB
+[SEE ALSO]
+.BR grub-reboot (8),
+.BR grub-editenv (1)
diff --git a/docs/man/grub-setup.h2m b/docs/man/grub-setup.h2m
new file mode 100644
index 0000000..eebe3ef
--- /dev/null
+++ b/docs/man/grub-setup.h2m
@@ -0,0 +1,6 @@
+[NAME]
+grub-setup \- set up a device to boot using GRUB
+[SEE ALSO]
+.BR grub-install (8),
+.BR grub-mkimage (1),
+.BR grub-mkrescue (1)
diff --git a/docs/mdate-sh b/docs/mdate-sh
new file mode 100644
index 0000000..22f2f8b
--- /dev/null
+++ b/docs/mdate-sh
@@ -0,0 +1,205 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2007-03-30.02
+
+# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005, 2007 Free Software
+# Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# 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, 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, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No file. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification time of FILE.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "mdate-sh $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable. Since we cannot assume `unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+ TIME_STYLE=posix-long-iso
+ export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ ls_command='ls -L -l -d'
+else
+ ls_command='ls -l -d'
+fi
+# Avoid user/group names that might have spaces, when possible.
+if ls -n /dev/null 1>/dev/null 2>&1; then
+ ls_command="$ls_command -n"
+fi
+
+# A `ls -l' line looks as follows on OS/2.
+# drwxrwx--- 0 Aug 11 2001 foo
+# This differs from Unix, which adds ownership information.
+# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month. This cannot work with files whose owner is a
+# user named `Jan', or `Feb', etc. However, it's unlikely that `/'
+# will be owned by a user whose name is a month. So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`$ls_command /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+ shift
+ # Add another shift to the command.
+ command="$command shift;"
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+ ???*) day=$1;;
+ *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/docs/stamp-1 b/docs/stamp-1
new file mode 100644
index 0000000..056836e
--- /dev/null
+++ b/docs/stamp-1
@@ -0,0 +1,4 @@
+@set UPDATED 13 April 2011
+@set UPDATED-MONTH April 2011
+@set EDITION 1.99
+@set VERSION 1.99
diff --git a/docs/stamp-vti b/docs/stamp-vti
new file mode 100644
index 0000000..647f8f7
--- /dev/null
+++ b/docs/stamp-vti
@@ -0,0 +1,4 @@
+@set UPDATED 14 May 2011
+@set UPDATED-MONTH May 2011
+@set EDITION 1.99
+@set VERSION 1.99
diff --git a/docs/texinfo.tex b/docs/texinfo.tex
new file mode 100644
index 0000000..0135d0c
--- /dev/null
+++ b/docs/texinfo.tex
@@ -0,0 +1,8959 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2007-09-03.05}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 2007,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007 Free Software Foundation, Inc.
+%
+% 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 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.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 program. If not, see <http://www.gnu.org/licenses/>.
+%
+% 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. 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}
+
+
+\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\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\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
+
+% 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{l.\the\inputlineno:\space}
+\fi
+
+% 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
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar = `\-
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar = `\;
+\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{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% 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
+ \errorcontextlines16
+}%
+
+% 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
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page. The solution is
+% described on page 260 of The TeXbook. It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after. I won't pretend I can describe this better than DEK...
+\def\domark{%
+ \toks0=\expandafter{\lastchapterdefs}%
+ \toks2=\expandafter{\lastsectiondefs}%
+ \toks4=\expandafter{\prevchapterdefs}%
+ \toks6=\expandafter{\prevsectiondefs}%
+ \toks8=\expandafter{\lastcolordefs}%
+ \mark{%
+ \the\toks0 \the\toks2
+ \noexpand\or \the\toks4 \the\toks6
+ \noexpand\else \the\toks8
+ }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+ \ifcase0\topmark\fi
+ \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% 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).
+ \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+ \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.
+ %
+ \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.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
+ \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 \oddfootingyyy.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 24pt
+ \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 \indexdummies
+ \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\relax \unvbox#1\relax
+\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\argtorun{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #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{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\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 now,
+% just before passing the control to \argtorun.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\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\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#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}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ out of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\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/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% 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 @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% 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
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+ \kern-.15em
+ \TeX
+}
+
+% 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=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+ \fi\fi
+}
+
+% @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}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % 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
+}
+%
+% The \vtop 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. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \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
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% 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.
+%\parseargdef\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
+%}}
+
+\parseargdef\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 (and is undocumented).
+
+\let\br = \par
+
+% @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.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\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.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\next\centerH
+ \else
+ \let\next\centerV
+ \fi
+ \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+ {%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+ }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n outputs n lines of vertical space
+
+\parseargdef\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}
+%
+\parseargdef\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.
+\parseargdef\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}
+\def\insertword{insert}
+%
+\parseargdef\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`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\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$\endgroup} % Close the group opened by \tex.
+
+% 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{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @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{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \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
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's what we do).
+
+% double active backslashes.
+%
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef@activebackslashdouble{%
+ @catcode`@\=@active
+ @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters. hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens, with minor
+% changes for Texinfo. It is included here under the GPL by permission
+% from the author, Heiko Oberdiek.
+%
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+%
+\def\HyPsdSubst#1#2#3{%
+ \def\HyPsdReplace##1#1##2\END{%
+ ##1%
+ \ifx\\##2\\%
+ \else
+ #2%
+ \HyReturnAfterFi{%
+ \HyPsdReplace##2\END
+ }%
+ \fi
+ }%
+ \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+ \xdef#1{#1}% redefine it as its expansion; the definition is simply
+ % \lastnode when called from \setref -> \pdfmkdest.
+ \HyPsdSubst{(}{\realbackslash(}{#1}%
+ \HyPsdSubst{)}{\realbackslash)}{#1}%
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found. (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+ %
+ % Color manipulation macros based on pdfcolor.tex.
+ \def\cmykDarkRed{0.28 1 1 0.35}
+ \def\cmykBlack{0 0 0 1}
+ %
+ \def\pdfsetcolor#1{\pdfliteral{#1 k}}
+ % Set color, and create a mark which defines \thiscolor accordingly,
+ % so that \makeheadline knows which color to restore.
+ \def\setcolor#1{%
+ \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+ \domark
+ \pdfsetcolor{#1}%
+ }
+ %
+ \def\maincolor{\cmykBlack}
+ \pdfsetcolor{\maincolor}
+ \edef\thiscolor{\maincolor}
+ \def\lastcolordefs{}
+ %
+ \def\makefootline{%
+ \baselineskip24pt
+ \line{\pdfsetcolor{\maincolor}\the\footline}%
+ }
+ %
+ \def\makeheadline{%
+ \vbox to 0pt{%
+ \vskip-22.5pt
+ \line{%
+ \vbox to8.5pt{}%
+ % Extract \thiscolor definition from the marks.
+ \getcolormarks
+ % Typeset the headline with \maincolor, then restore the color.
+ \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+ }%
+ \vss
+ }%
+ \nointerlineskip
+ }
+ %
+ %
+ \pdfcatalog{/PageMode /UseOutlines}
+ %
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \def\dopdfimage#1#2#3{%
+ \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ %
+ % pdftex (and the PDF format) support .png, .jpg, .pdf (among
+ % others). Let's try in that order.
+ \let\pdfimgext=\empty
+ \begingroup
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
+ \openin 1 #1.pdf \ifeof 1
+ \errhelp = \nopdfimagehelp
+ \errmessage{Could not find image file #1 for pdf}%
+ \else \gdef\pdfimgext{pdf}%
+ \fi
+ \else \gdef\pdfimgext{JPG}%
+ \fi
+ \else \gdef\pdfimgext{jpeg}%
+ \fi
+ \else \gdef\pdfimgext{jpg}%
+ \fi
+ \else \gdef\pdfimgext{png}%
+ \fi
+ \closein 1
+ \endgroup
+ %
+ % 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
+ \ifdim \wd0 >0pt width \imagewidth \fi
+ \ifdim \wd2 >0pt height \imageheight \fi
+ \ifnum\pdftexversion<13
+ #1.\pdfimgext
+ \else
+ {#1.\pdfimgext}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ %
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \indexnofonts
+ \turnoffactive
+ \activebackslashdouble
+ \makevalueexpandable
+ \def\pdfdestname{#1}%
+ \backslashparens\pdfdestname
+ \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+ }}
+ %
+ % used to mark target names; must be expandable.
+ \def\pdfmkpgn#1{#1}
+ %
+ % by default, use a color that is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing.
+ \def\urlcolor{\cmykDarkRed}
+ \def\linkcolor{\cmykDarkRed}
+ \def\endlink{\setcolor{\maincolor}\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, which is what will be displayed in the
+ % outline by the pdf viewer. #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 worth the trouble, since most documents are normally structured.
+ \def\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ % Doubled backslashes in the name.
+ {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+ \backslashparens\pdfoutlinedest}%
+ \fi
+ %
+ % Also double the backslashes in the display string.
+ {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+ \backslashparens\pdfoutlinetext}%
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % 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\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % 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}%
+ \readdatafile{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}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % xx to do this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Right
+ % now, I guess we'll just let the pdf reader have its way.
+ \indexnofonts
+ \setupdatafile
+ \catcode`\\=\active \otherbackslash
+ \input \tocreadfilename
+ \endgroup
+ }
+ %
+ \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
+ % make a live url in pdf output.
+ \def\pdfurl#1{%
+ \begingroup
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
+ \makevalueexpandable
+ \leavevmode\setcolor{\urlcolor}%
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#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|\relax
+ \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}}
+ \setcolor{\linkcolor}#1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\setcolor = \gobble
+ \let\pdfsetcolor = \gobble
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% 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}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\def\setleading#1{%
+ \dimen0 = #1\relax
+ \normalbaselineskip = \baselinefactor\dimen0
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+%
+% PDF CMaps. See also LaTeX's t1.cmap.
+%
+% \cmapOT1
+\ifpdf
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1IT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1TT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+\else
+ \expandafter\let\csname cmapOT1\endcsname\gobble
+ \expandafter\let\csname cmapOT1IT\endcsname\gobble
+ \expandafter\let\csname cmapOT1TT\endcsname\gobble
+\fi
+
+
+% 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, #5 is the CMap
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
+\def\setfont#1#2#3#4#5{%
+ \font#1=\fontprefix#2#3 scaled #4
+ \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+
+
+% 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}
+
+% Definitions for a main text size of 11pt. This is the default in
+% Texinfo.
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 11pt text font size definitions
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+% reduce space between paragraphs
+\divide\parskip by 2
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 10pt text font size definitions
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xword{10}
+\def\xiword{11}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ \wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
+
+% 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 because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\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
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \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
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \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
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \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
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \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
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\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
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \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
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \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 \scriptfonts (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 the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+% 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.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+%% 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\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% 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\plainfrenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
+ }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+\def\t#1{%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
+ \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}{OT1}
+\font\keysy=cmsy9
+\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}}}}
+\def\key #1{{\nohyphenation \uppercase{#1}}\null}
+% 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
+ \plainfrenchspacing
+ #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
+ \catcode`\'=\active \catcode`\`=\active
+ %
+ \global\def\code{\begingroup
+ \catcode\rquoteChar=\active \catcode\lquoteChar=\active
+ \let'\codequoteright \let`\codequoteleft
+ %
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\realdash
+ \let_\realunder
+ \fi
+ \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}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general. @allowcodebreaks provides a way to control this.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+ \fi\fi
+}
+
+% @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).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+ \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 @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\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}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% 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 for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\plainfrenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% Hacks for glyphs from the EC fonts similar to \euro. We don't
+% use \let for the aliases, because sometimes we redefine the original
+% macro, and the alias should reflect the redefinition.
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+\def\ecfont{%
+ % We can't distinguish serif/sanserif and italic/slanted, but this
+ % is used for crude hacks anyway (like adding French and German
+ % quotes to documents typeset with CM, where we lose kerning), so
+ % hopefully nobody will notice/care.
+ \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+ \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
+ \thisecfont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+\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
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \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}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \leftline{\titlefonts\rm #1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\authorfont \leftline{#1}}%
+ \fi
+}
+
+
+%%% 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}}}
+
+\parseargdef\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 -12pt
+ \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+ \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+ \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+ \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+ \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @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. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted 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. Section titles are handled this way also.
+ %
+ \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.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\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}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ \def\itemcontents{#1}%
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \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'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % 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 \doitemize, 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
+ \doitemize{#1.}\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}
+
+
+% @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 @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\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.
+%
+% @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. Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\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{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % 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.
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % 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
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \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\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\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,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\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}}
+
+% 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:
+ \obeylines
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % 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 command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1'.
+ \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.
+ \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.
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\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.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \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.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \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.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @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 macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \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{%
+ \escapechar = `\\ % use backslash in output files.
+ \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
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ %
+ % The above is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % Do the redefinitions.
+ \commondummies
+ \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+ %
+ % \definedummyword defines \#1 as \string\#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{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter\_%
+ %
+ % 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
+ \definedummyword\exclamdown
+ \definedummyword\questiondown
+ \definedummyword\ordf
+ \definedummyword\ordm
+ %
+ % 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
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
+ %
+ % Assorted special characters.
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\guillemetleft
+ \definedummyword\guillemetright
+ \definedummyword\guilsinglleft
+ \definedummyword\guilsinglright
+ \definedummyword\expansion
+ \definedummyword\minus
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\quotedblbase
+ \definedummyword\quotedblleft
+ \definedummyword\quotedblright
+ \definedummyword\quoteleft
+ \definedummyword\quoteright
+ \definedummyword\quotesinglbase
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sc
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\acronym
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
+}
+
+% \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\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{\let##1\asis}%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{\let##1\empty}%
+ % Hopefully, all control words can become @asis.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % 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
+ %
+ \def\ { }%
+ \def\@{@}%
+ % how to handle braces?
+ \def\_{\normalunderscore}%
+ %
+ % 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{?}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\registeredsymbol{R}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\guillemetleft{<<}%
+ \def\guillemetright{>>}%
+ \def\guilsinglleft{<}%
+ \def\guilsinglright{>}%
+ \def\expansion{==>}%
+ \def\minus{-}%
+ \def\pounds{pounds}%
+ \def\point{.}%
+ \def\print{-|}%
+ \def\quotedblbase{"}%
+ \def\quotedblleft{"}%
+ \def\quotedblright{"}%
+ \def\quoteleft{`}%
+ \def\quoteright{'}%
+ \def\quotesinglbase{,}%
+ \def\result{=>}%
+ \def\textdegree{degrees}%
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
+}
+
+\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}%
+ %
+ \safewhatsit\dosubindwrite
+ }%
+ \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
+ \def\backslashcurfont{\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/skips around a whatsit:
+%
+% 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 or \pdfdest 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}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{%
+\ifhmode
+ #1%
+\else
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \whatsitskip = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \whatsitpenalty = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\whatsitskip 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-\whatsitskip
+ \fi
+ %
+ #1%
+ %
+ \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 same penalty (values >10000 are used for various
+ % signals); 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\whatsitpenalty>9999 \penalty\whatsitpenalty \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\whatsitskip
+ \fi
+\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).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \plainfrenchspacing
+ \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{\backslashcurfont}%
+ \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.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % 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}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \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 straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% 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.
+ \setbox\boxA = \hbox{#1}%
+ \ifdim\wd\boxA = 0pt
+ \ %
+ \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 plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\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{%
+ % The following penalty ensures that the page builder is exercised
+ % _before_ we change the output routine. This is necessary in the
+ % following situation:
+ %
+ % The last section of the index consists only of a single entry.
+ % Before this section, \pagetotal is less than \pagegoal, so no
+ % break occurs before the last section starts. However, the last
+ % section, consisting of \initial and the single \entry, does not
+ % fit on the page and has to be broken off. Without the following
+ % penalty the page builder will not be exercised until \eject
+ % below, and by that time we'll already have changed the output
+ % routine to the \balancecolumns version, so the next-to-last
+ % double-column page will be processed with \balancecolumns, which
+ % is wrong: The two columns will go to the main vertical list, with
+ % the broken-off section in the recent contributions. As soon as
+ % the output routine finishes, TeX starts reconsidering the page
+ % break. The two columns and the broken-off section both fit on the
+ % page, because the two columns now take up only half of the page
+ % goal. When TeX sees \eject from below which follows the final
+ % section, it invokes the new output routine that we've set after
+ % \balancecolumns below; \onepageout will try to fit the two columns
+ % and the final section into the vbox of \pageheight (see
+ % \pagebody), causing an overfull box.
+ %
+ % Note that glue won't work here, because glue does not exercise the
+ % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+ \penalty0
+ %
+ \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 these (using marks) as the number+name, number
+% and name of the chapter. Page headings and footings can use
+% these. @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\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
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unmlevel
+ \chardef\unmlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unmlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unmlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\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
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ \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\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ \def\appendixnum{\putwordAppendix\space \appendixletter}%
+ \message{\appendixnum}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % 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
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\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\parseargdef\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\parseargdef\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\parseargdef\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\parseargdef\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\parseargdef\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\parseargdef\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\parseargdef\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\parseargdef\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 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.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\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}
+
+%%% 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}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong. But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+ \chappager
+ \ifodd\pageno \else
+ \begingroup
+ \evenheadline={\hfil}\evenfootline={\hfil}%
+ \oddheadline={\hfil}\oddfootline={\hfil}%
+ \hbox to 0pt{}%
+ \chappager
+ \endgroup
+ \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
+
+% 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\chapmacro#1#2#3{%
+ % Insert the first mark before the heading break (see notes for \domark).
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+ \gdef\thissection{}}%
+ %
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{\thischaptername}}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{}}%
+ \else\ifx\temptype\Yappendixkeyword
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\appendixletter}%
+ \gdef\noexpand\thischapter{\putwordAppendix{} \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \else
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\the\chapno}%
+ \gdef\noexpand\thischapter{\putwordChapter{} \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \fi\fi\fi
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert the chapter heading break.
+ \pchapsepmacro
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ {%
+ \chapfonts \rm
+ %
+ % Have to define \lastsection 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\lastsection{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \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.
+ \nobreak % Avoid page breaks at the interline glue.
+ \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\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% 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\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\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\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rm
+ %
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ % Insert first mark before the heading break (see notes for \domark).
+ \let\prevsectiondefs=\lastsectiondefs
+ \ifx\temptype\Ynothingkeyword
+ \ifx\sectionlevel\seckeyword
+ \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+ \gdef\thissection{\thissectionname}}%
+ \fi
+ \else\ifx\temptype\Yomitfromtockeyword
+ % Don't redefine \thissection.
+ \else\ifx\temptype\Yappendixkeyword
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \else
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \fi\fi\fi
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ % Only insert the space after the number if we have a section number.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\lastsection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \lastsection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\lastsection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\lastsection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chapmacro.
+ \donoderef{#3}%
+ %
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
+ % 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 is purely so the last item on the list is a known \penalty >
+ % 10000. This is so \startdefun can avoid allowing breakpoints after
+ % section headings. Otherwise, it would insert a valid breakpoint between:
+ %
+ % @section sec-whatever
+ % @deffn def-whatever
+ \penalty 10001
+}
+
+
+\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
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\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
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \tocreadfilename
+}
+
+\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.
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \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
+}
+
+% redefined for the two-volume lispref. We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \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 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \closein 1
+ \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.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% 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 \reducedsf 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.
+
+\envdef\tex{%
+ \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
+ \let\frenchspacing=\plainfrenchspacing
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group 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 and
+ % \sectionheading, 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 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\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
+
+\envdef\cartouche{%
+ \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 = t%
+ \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
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \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
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ % end paragraph for sake of leading, in case document has no blank
+ % line. This is redundant with what happens in \aboveenvbreak, but
+ % we need to do it before changing the fonts, and it's inconvenient
+ % to change the fonts afterward.
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+ \makedispenv{#1}{#3}
+ \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+ \nonfillstart
+ \tt\quoteexpand
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\undefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+
+% 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}
+
+% Allow an option to not replace quotes with a regular directed right
+% quote/apostrophe (char 0x27), but instead use the undirected quote
+% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it
+% the default, but it works for pasting with more pdf viewers (at least
+% evince), the lilypond developers report. xpdf does work with the
+% regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else \char'15 \fi
+ \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ `%
+ \else \char'22 \fi
+ \else \char'22 \fi
+}
+%
+\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
+ }%
+ }
+ \catcode`\'=\active
+ \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}%
+ %
+ \catcode`\`=\active
+ \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}%
+ %
+ \gdef\quoteexpand{\rquoteexpand \lquoteexpand}%
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ % Easiest (and conventionally used) font for verbatim
+ \tt
+ \def\par{\leavevmode\egroup\box0\endgraf}%
+ \catcode`\`=\active
+ \tabexpand
+ \quoteexpand
+ % 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
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% 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{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \defunpenalty=10003 % Will keep this @deffn together with the
+ % following @def command, see below.
+ \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 specifically for penalty 10002, inserted
+ % by \printdefunline, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ % As a minor refinement, we avoid "club" headers by signalling
+ % with penalty of 10003 after the very first @deffn in the
+ % sequence (see above), and penalty of 10002 after any following
+ % @def command.
+ \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \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
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#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 \else \defunpenalty=10002 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty\defunpenalty % 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\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{%
+ \envdef#1{%
+ \startdefun
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#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 \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#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}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#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}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\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.
+}
+
+% Print arguments in slanted roman (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. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. Let's try @var for that.
+ \let\var=\ttslanted
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+ \message{Warning: unbalanced parentheses in @def...}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \message{Warning: unbalanced square brackets 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\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{%
+ \begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ % ... and \example
+ \spaceisspace
+ %
+ % Append \endinput to make sure that TeX does not see the ending newline.
+ % I've verified that it is necessary both for e-TeX and for ordinary TeX
+ % --kasal, 29nov03
+ \scantokens{#1\endinput}%
+ \endgroup
+}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\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 \.
+
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion. Must do this non-globally, to
+% confine the change to the current group.
+
+% 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\scanctxt{%
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+ \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{%
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{%
+ \scanctxt
+ \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%
+ \addtomacrolist{\the\macname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\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\definedummyword\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\definedummyword \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\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \macnamexxx}
+
+
+% @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
+ \addtomacrolist{#1}%
+ \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. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#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
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\lastsection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \safewhatsit{\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\printedrefname{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual\unskip}%
+ \setbox0=\hbox{\printedrefname\unskip}%
+ \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\printedrefname{\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\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ \leavevmode
+ \getfilename{#4}%
+ {\indexnofonts
+ \turnoffactive
+ % See comments at \activebackslashdouble.
+ {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+ \backslashparens\pdfxrefdest}%
+ %
+ \ifnum\filenamelength>0
+ \startlink attr{/Border [0 0 0]}%
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
+ \else
+ \startlink attr{/Border [0 0 0]}%
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
+ \fi
+ }%
+ \setcolor{\linkcolor}%
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd0 = 0pt
+ \refx{#1-snt}{}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % if the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd1 > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % 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.
+ \ifdim \wd1 > 0pt
+ \putwordSection{} ``\printedrefname'' \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
+ % 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 so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+ \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 square brackets don't work well 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
+}
+
+% 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 XR#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. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ {% The node name might contain 8-bit characters, which in our current
+ % implementation are changed to commands like @'e. Don't let these
+ % mess up the control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safexrefname{#1}%
+ }%
+ %
+ \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR\safexrefname\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+ {\safexrefname}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readdatafile{aux}%
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\setupdatafile{%
+ \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
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count1=128
+ \def\loop{%
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
+\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 replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\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%
+ \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
+ % 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
+\closein 1
+%
+% 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
+ \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 \egroup \bigbreak \fi % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \lastsection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\lastsection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies
+ %
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+
+\message{localization,}
+
+% @documentlanguage is usually given very early, just after
+% @setfilename. If done too late, it may not override everything
+% properly. Single argument is the language (de) or locale (de_DE)
+% abbreviation. It would be nice if we could set up a hyphenation file.
+%
+{
+ \catcode`\_ = \active
+ \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+ \let_=\normalunderscore % normal _ character for filenames
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file by the name they passed if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \documentlanguagetrywithoutunderscore{#1_\finish}%
+ \else
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup
+\endgroup}
+}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\def\documentlanguagetrywithoutunderscore#1_#2\finish{%
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \input txi-#1.tex
+ \fi
+ \closein 1
+}
+%
+\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.}
+
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \global\catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+ % Encoding being declared for the document.
+ \def\declaredencoding{\csname #1.enc\endcsname}%
+ %
+ % Supported encodings: names converted to tokens in order to be able
+ % to compare them with \ifx.
+ \def\ascii{\csname US-ASCII.enc\endcsname}%
+ \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+ \def\latone{\csname ISO-8859-1.enc\endcsname}%
+ \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+ \def\utfeight{\csname UTF-8.enc\endcsname}%
+ %
+ \ifx \declaredencoding \ascii
+ \asciichardefs
+ %
+ \else \ifx \declaredencoding \lattwo
+ \setnonasciicharscatcode\active
+ \lattwochardefs
+ %
+ \else \ifx \declaredencoding \latone
+ \setnonasciicharscatcode\active
+ \latonechardefs
+ %
+ \else \ifx \declaredencoding \latnine
+ \setnonasciicharscatcode\active
+ \latninechardefs
+ %
+ \else \ifx \declaredencoding \utfeight
+ \setnonasciicharscatcode\active
+ \utfeightchardefs
+ %
+ \else
+ \message{Unknown document encoding #1, ignoring.}%
+ %
+ \fi % utfeight
+ \fi % latnine
+ \fi % latone
+ \fi % lattwo
+ \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+ \gdef^^a0{~}
+ \gdef^^a1{\exclamdown}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a3{{\pounds}}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\missingcharmsg{YEN SIGN}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
+ \gdef^^aa{\ordf}
+ \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+ \gdef^^ac{$\lnot$}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
+ \gdef^^af{\={}}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{$\pm$}
+ \gdef^^b2{$^2$}
+ \gdef^^b3{$^3$}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{$\mu$}
+ \gdef^^b6{\P}
+ %
+ \gdef^^b7{$^.$}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{$^1$}
+ \gdef^^ba{\ordm}
+ %
+ \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+ \gdef^^bc{$1\over4$}
+ \gdef^^bd{$1\over2$}
+ \gdef^^be{$3\over4$}
+ \gdef^^bf{\questiondown}
+ %
+ \gdef^^c0{\`A}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\~A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\ringaccent A}
+ \gdef^^c6{\AE}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\`E}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\^E}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\`I}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\"I}
+ %
+ \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}}
+ \gdef^^d1{\~N}
+ \gdef^^d2{\`O}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\~O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\O}
+ \gdef^^d9{\`U}
+ \gdef^^da{\'U}
+ \gdef^^db{\^U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\`a}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\~a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\ringaccent a}
+ \gdef^^e6{\ae}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\`e}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\^e}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\`{\dotless i}}
+ \gdef^^ed{\'{\dotless i}}
+ \gdef^^ee{\^{\dotless i}}
+ \gdef^^ef{\"{\dotless i}}
+ %
+ \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}}
+ \gdef^^f1{\~n}
+ \gdef^^f2{\`o}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\~o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\o}
+ \gdef^^f9{\`u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\^u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}}
+ \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+ % Encoding is almost identical to Latin1.
+ \latonechardefs
+ %
+ \gdef^^a4{\euro}
+ \gdef^^a6{\v S}
+ \gdef^^a8{\v s}
+ \gdef^^b4{\v Z}
+ \gdef^^b8{\v z}
+ \gdef^^bc{\OE}
+ \gdef^^bd{\oe}
+ \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+ \gdef^^a0{~}
+ \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}}
+ \gdef^^a2{\u{}}
+ \gdef^^a3{\L}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\v L}
+ \gdef^^a6{\'S}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\v S}
+ \gdef^^aa{\cedilla S}
+ \gdef^^ab{\v T}
+ \gdef^^ac{\'Z}
+ \gdef^^ad{\-}
+ \gdef^^ae{\v Z}
+ \gdef^^af{\dotaccent Z}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}}
+ \gdef^^b2{\missingcharmsg{OGONEK}}
+ \gdef^^b3{\l}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{\v l}
+ \gdef^^b6{\'s}
+ \gdef^^b7{\v{}}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{\v s}
+ \gdef^^ba{\cedilla s}
+ \gdef^^bb{\v t}
+ \gdef^^bc{\'z}
+ \gdef^^bd{\H{}}
+ \gdef^^be{\v z}
+ \gdef^^bf{\dotaccent z}
+ %
+ \gdef^^c0{\'R}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\u A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\'L}
+ \gdef^^c6{\'C}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\v C}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\v E}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\v D}
+ %
+ \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}}
+ \gdef^^d1{\'N}
+ \gdef^^d2{\v N}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\H O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\v R}
+ \gdef^^d9{\ringaccent U}
+ \gdef^^da{\'U}
+ \gdef^^db{\H U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\cedilla T}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\'r}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\u a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\'l}
+ \gdef^^e6{\'c}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\v c}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\v e}
+ \gdef^^ed{\'\i}
+ \gdef^^ee{\^\i}
+ \gdef^^ef{\v d}
+ %
+ \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}}
+ \gdef^^f1{\'n}
+ \gdef^^f2{\v n}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\H o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\v r}
+ \gdef^^f9{\ringaccent u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\H u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\cedilla t}
+ \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions. It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+ \ifx #1\relax
+ \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+ \else
+ \expandafter #1%
+ \fi
+}
+
+\begingroup
+ \catcode`\~13
+ \catcode`\"12
+
+ \def\UTFviiiLoop{%
+ \global\catcode\countUTFx\active
+ \uccode`\~\countUTFx
+ \uppercase\expandafter{\UTFviiiTmp}%
+ \advance\countUTFx by 1
+ \ifnum\countUTFx < \countUTFy
+ \expandafter\UTFviiiLoop
+ \fi}
+
+ \countUTFx = "C2
+ \countUTFy = "E0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "E0
+ \countUTFy = "F0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "F0
+ \countUTFy = "F4
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+ \UTFviiiLoop
+\endgroup
+
+\begingroup
+ \catcode`\"=12
+ \catcode`\<=12
+ \catcode`\.=12
+ \catcode`\,=12
+ \catcode`\;=12
+ \catcode`\!=12
+ \catcode`\~=13
+
+ \gdef\DeclareUnicodeCharacter#1#2{%
+ \countUTFz = "#1\relax
+ \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ \begingroup
+ \parseXMLCharref
+ \def\UTFviiiTwoOctets##1##2{%
+ \csname u8:##1\string ##2\endcsname}%
+ \def\UTFviiiThreeOctets##1##2##3{%
+ \csname u8:##1\string ##2\string ##3\endcsname}%
+ \def\UTFviiiFourOctets##1##2##3##4{%
+ \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter
+ \gdef\UTFviiiTmp{#2}%
+ \endgroup}
+
+ \gdef\parseXMLCharref{%
+ \ifnum\countUTFz < "A0\relax
+ \errhelp = \EMsimple
+ \errmessage{Cannot define Unicode char value < 00A0}%
+ \else\ifnum\countUTFz < "800\relax
+ \parseUTFviiiA,%
+ \parseUTFviiiB C\UTFviiiTwoOctets.,%
+ \else\ifnum\countUTFz < "10000\relax
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+ \else
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiA!%
+ \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+ \fi\fi\fi
+ }
+
+ \gdef\parseUTFviiiA#1{%
+ \countUTFx = \countUTFz
+ \divide\countUTFz by 64
+ \countUTFy = \countUTFz
+ \multiply\countUTFz by 64
+ \advance\countUTFx by -\countUTFz
+ \advance\countUTFx by 128
+ \uccode `#1\countUTFx
+ \countUTFz = \countUTFy}
+
+ \gdef\parseUTFviiiB#1#2#3#4{%
+ \advance\countUTFz by "#10\relax
+ \uccode `#3\countUTFz
+ \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+ \DeclareUnicodeCharacter{00A0}{\tie}
+ \DeclareUnicodeCharacter{00A1}{\exclamdown}
+ \DeclareUnicodeCharacter{00A3}{\pounds}
+ \DeclareUnicodeCharacter{00A8}{\"{ }}
+ \DeclareUnicodeCharacter{00A9}{\copyright}
+ \DeclareUnicodeCharacter{00AA}{\ordf}
+ \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+ \DeclareUnicodeCharacter{00AD}{\-}
+ \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+ \DeclareUnicodeCharacter{00AF}{\={ }}
+
+ \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+ \DeclareUnicodeCharacter{00B4}{\'{ }}
+ \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+ \DeclareUnicodeCharacter{00BA}{\ordm}
+ \DeclareUnicodeCharacter{00BB}{\guillemetright}
+ \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+ \DeclareUnicodeCharacter{00C0}{\`A}
+ \DeclareUnicodeCharacter{00C1}{\'A}
+ \DeclareUnicodeCharacter{00C2}{\^A}
+ \DeclareUnicodeCharacter{00C3}{\~A}
+ \DeclareUnicodeCharacter{00C4}{\"A}
+ \DeclareUnicodeCharacter{00C5}{\AA}
+ \DeclareUnicodeCharacter{00C6}{\AE}
+ \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+ \DeclareUnicodeCharacter{00C8}{\`E}
+ \DeclareUnicodeCharacter{00C9}{\'E}
+ \DeclareUnicodeCharacter{00CA}{\^E}
+ \DeclareUnicodeCharacter{00CB}{\"E}
+ \DeclareUnicodeCharacter{00CC}{\`I}
+ \DeclareUnicodeCharacter{00CD}{\'I}
+ \DeclareUnicodeCharacter{00CE}{\^I}
+ \DeclareUnicodeCharacter{00CF}{\"I}
+
+ \DeclareUnicodeCharacter{00D1}{\~N}
+ \DeclareUnicodeCharacter{00D2}{\`O}
+ \DeclareUnicodeCharacter{00D3}{\'O}
+ \DeclareUnicodeCharacter{00D4}{\^O}
+ \DeclareUnicodeCharacter{00D5}{\~O}
+ \DeclareUnicodeCharacter{00D6}{\"O}
+ \DeclareUnicodeCharacter{00D8}{\O}
+ \DeclareUnicodeCharacter{00D9}{\`U}
+ \DeclareUnicodeCharacter{00DA}{\'U}
+ \DeclareUnicodeCharacter{00DB}{\^U}
+ \DeclareUnicodeCharacter{00DC}{\"U}
+ \DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DF}{\ss}
+
+ \DeclareUnicodeCharacter{00E0}{\`a}
+ \DeclareUnicodeCharacter{00E1}{\'a}
+ \DeclareUnicodeCharacter{00E2}{\^a}
+ \DeclareUnicodeCharacter{00E3}{\~a}
+ \DeclareUnicodeCharacter{00E4}{\"a}
+ \DeclareUnicodeCharacter{00E5}{\aa}
+ \DeclareUnicodeCharacter{00E6}{\ae}
+ \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+ \DeclareUnicodeCharacter{00E8}{\`e}
+ \DeclareUnicodeCharacter{00E9}{\'e}
+ \DeclareUnicodeCharacter{00EA}{\^e}
+ \DeclareUnicodeCharacter{00EB}{\"e}
+ \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+ \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{00F1}{\~n}
+ \DeclareUnicodeCharacter{00F2}{\`o}
+ \DeclareUnicodeCharacter{00F3}{\'o}
+ \DeclareUnicodeCharacter{00F4}{\^o}
+ \DeclareUnicodeCharacter{00F5}{\~o}
+ \DeclareUnicodeCharacter{00F6}{\"o}
+ \DeclareUnicodeCharacter{00F8}{\o}
+ \DeclareUnicodeCharacter{00F9}{\`u}
+ \DeclareUnicodeCharacter{00FA}{\'u}
+ \DeclareUnicodeCharacter{00FB}{\^u}
+ \DeclareUnicodeCharacter{00FC}{\"u}
+ \DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FF}{\"y}
+
+ \DeclareUnicodeCharacter{0100}{\=A}
+ \DeclareUnicodeCharacter{0101}{\=a}
+ \DeclareUnicodeCharacter{0102}{\u{A}}
+ \DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0106}{\'C}
+ \DeclareUnicodeCharacter{0107}{\'c}
+ \DeclareUnicodeCharacter{0108}{\^C}
+ \DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+ \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+ \DeclareUnicodeCharacter{010C}{\v{C}}
+ \DeclareUnicodeCharacter{010D}{\v{c}}
+ \DeclareUnicodeCharacter{010E}{\v{D}}
+
+ \DeclareUnicodeCharacter{0112}{\=E}
+ \DeclareUnicodeCharacter{0113}{\=e}
+ \DeclareUnicodeCharacter{0114}{\u{E}}
+ \DeclareUnicodeCharacter{0115}{\u{e}}
+ \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+ \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+ \DeclareUnicodeCharacter{011A}{\v{E}}
+ \DeclareUnicodeCharacter{011B}{\v{e}}
+ \DeclareUnicodeCharacter{011C}{\^G}
+ \DeclareUnicodeCharacter{011D}{\^g}
+ \DeclareUnicodeCharacter{011E}{\u{G}}
+ \DeclareUnicodeCharacter{011F}{\u{g}}
+
+ \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+ \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+ \DeclareUnicodeCharacter{0124}{\^H}
+ \DeclareUnicodeCharacter{0125}{\^h}
+ \DeclareUnicodeCharacter{0128}{\~I}
+ \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+ \DeclareUnicodeCharacter{012A}{\=I}
+ \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+ \DeclareUnicodeCharacter{012C}{\u{I}}
+ \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+ \DeclareUnicodeCharacter{0131}{\dotless{i}}
+ \DeclareUnicodeCharacter{0132}{IJ}
+ \DeclareUnicodeCharacter{0133}{ij}
+ \DeclareUnicodeCharacter{0134}{\^J}
+ \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+ \DeclareUnicodeCharacter{0139}{\'L}
+ \DeclareUnicodeCharacter{013A}{\'l}
+
+ \DeclareUnicodeCharacter{0141}{\L}
+ \DeclareUnicodeCharacter{0142}{\l}
+ \DeclareUnicodeCharacter{0143}{\'N}
+ \DeclareUnicodeCharacter{0144}{\'n}
+ \DeclareUnicodeCharacter{0147}{\v{N}}
+ \DeclareUnicodeCharacter{0148}{\v{n}}
+ \DeclareUnicodeCharacter{014C}{\=O}
+ \DeclareUnicodeCharacter{014D}{\=o}
+ \DeclareUnicodeCharacter{014E}{\u{O}}
+ \DeclareUnicodeCharacter{014F}{\u{o}}
+
+ \DeclareUnicodeCharacter{0150}{\H{O}}
+ \DeclareUnicodeCharacter{0151}{\H{o}}
+ \DeclareUnicodeCharacter{0152}{\OE}
+ \DeclareUnicodeCharacter{0153}{\oe}
+ \DeclareUnicodeCharacter{0154}{\'R}
+ \DeclareUnicodeCharacter{0155}{\'r}
+ \DeclareUnicodeCharacter{0158}{\v{R}}
+ \DeclareUnicodeCharacter{0159}{\v{r}}
+ \DeclareUnicodeCharacter{015A}{\'S}
+ \DeclareUnicodeCharacter{015B}{\'s}
+ \DeclareUnicodeCharacter{015C}{\^S}
+ \DeclareUnicodeCharacter{015D}{\^s}
+ \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+ \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+ \DeclareUnicodeCharacter{0160}{\v{S}}
+ \DeclareUnicodeCharacter{0161}{\v{s}}
+ \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+ \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+ \DeclareUnicodeCharacter{0164}{\v{T}}
+
+ \DeclareUnicodeCharacter{0168}{\~U}
+ \DeclareUnicodeCharacter{0169}{\~u}
+ \DeclareUnicodeCharacter{016A}{\=U}
+ \DeclareUnicodeCharacter{016B}{\=u}
+ \DeclareUnicodeCharacter{016C}{\u{U}}
+ \DeclareUnicodeCharacter{016D}{\u{u}}
+ \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+ \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+ \DeclareUnicodeCharacter{0170}{\H{U}}
+ \DeclareUnicodeCharacter{0171}{\H{u}}
+ \DeclareUnicodeCharacter{0174}{\^W}
+ \DeclareUnicodeCharacter{0175}{\^w}
+ \DeclareUnicodeCharacter{0176}{\^Y}
+ \DeclareUnicodeCharacter{0177}{\^y}
+ \DeclareUnicodeCharacter{0178}{\"Y}
+ \DeclareUnicodeCharacter{0179}{\'Z}
+ \DeclareUnicodeCharacter{017A}{\'z}
+ \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+ \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+ \DeclareUnicodeCharacter{017D}{\v{Z}}
+ \DeclareUnicodeCharacter{017E}{\v{z}}
+
+ \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+ \DeclareUnicodeCharacter{01C5}{D\v{z}}
+ \DeclareUnicodeCharacter{01C6}{d\v{z}}
+ \DeclareUnicodeCharacter{01C7}{LJ}
+ \DeclareUnicodeCharacter{01C8}{Lj}
+ \DeclareUnicodeCharacter{01C9}{lj}
+ \DeclareUnicodeCharacter{01CA}{NJ}
+ \DeclareUnicodeCharacter{01CB}{Nj}
+ \DeclareUnicodeCharacter{01CC}{nj}
+ \DeclareUnicodeCharacter{01CD}{\v{A}}
+ \DeclareUnicodeCharacter{01CE}{\v{a}}
+ \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+ \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+ \DeclareUnicodeCharacter{01D1}{\v{O}}
+ \DeclareUnicodeCharacter{01D2}{\v{o}}
+ \DeclareUnicodeCharacter{01D3}{\v{U}}
+ \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+ \DeclareUnicodeCharacter{01E2}{\={\AE}}
+ \DeclareUnicodeCharacter{01E3}{\={\ae}}
+ \DeclareUnicodeCharacter{01E6}{\v{G}}
+ \DeclareUnicodeCharacter{01E7}{\v{g}}
+ \DeclareUnicodeCharacter{01E8}{\v{K}}
+ \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+ \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+ \DeclareUnicodeCharacter{01F1}{DZ}
+ \DeclareUnicodeCharacter{01F2}{Dz}
+ \DeclareUnicodeCharacter{01F3}{dz}
+ \DeclareUnicodeCharacter{01F4}{\'G}
+ \DeclareUnicodeCharacter{01F5}{\'g}
+ \DeclareUnicodeCharacter{01F8}{\`N}
+ \DeclareUnicodeCharacter{01F9}{\`n}
+ \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+ \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+ \DeclareUnicodeCharacter{01FE}{\'{\O}}
+ \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+ \DeclareUnicodeCharacter{021E}{\v{H}}
+ \DeclareUnicodeCharacter{021F}{\v{h}}
+
+ \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+ \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+ \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+ \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+ \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+ \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+ \DeclareUnicodeCharacter{0232}{\=Y}
+ \DeclareUnicodeCharacter{0233}{\=y}
+ \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+ \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+ \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+ \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+ \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+ \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+ \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+ \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+ \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+ \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+ \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+ \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+ \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+ \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+ \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+ \DeclareUnicodeCharacter{1E20}{\=G}
+ \DeclareUnicodeCharacter{1E21}{\=g}
+ \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+ \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+ \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+ \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+ \DeclareUnicodeCharacter{1E26}{\"H}
+ \DeclareUnicodeCharacter{1E27}{\"h}
+
+ \DeclareUnicodeCharacter{1E30}{\'K}
+ \DeclareUnicodeCharacter{1E31}{\'k}
+ \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+ \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+ \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+ \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+ \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+ \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+ \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+ \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+ \DeclareUnicodeCharacter{1E3E}{\'M}
+ \DeclareUnicodeCharacter{1E3F}{\'m}
+
+ \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+ \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+ \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+ \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+ \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+ \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+ \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+ \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+ \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+ \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+ \DeclareUnicodeCharacter{1E54}{\'P}
+ \DeclareUnicodeCharacter{1E55}{\'p}
+ \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+ \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+ \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+ \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+ \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+ \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+ \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+ \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+ \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+ \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+ \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+ \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+ \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+ \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+ \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+ \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+ \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+ \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+ \DeclareUnicodeCharacter{1E7C}{\~V}
+ \DeclareUnicodeCharacter{1E7D}{\~v}
+ \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+ \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+ \DeclareUnicodeCharacter{1E80}{\`W}
+ \DeclareUnicodeCharacter{1E81}{\`w}
+ \DeclareUnicodeCharacter{1E82}{\'W}
+ \DeclareUnicodeCharacter{1E83}{\'w}
+ \DeclareUnicodeCharacter{1E84}{\"W}
+ \DeclareUnicodeCharacter{1E85}{\"w}
+ \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+ \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+ \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+ \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+ \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+ \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+ \DeclareUnicodeCharacter{1E8C}{\"X}
+ \DeclareUnicodeCharacter{1E8D}{\"x}
+ \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+ \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+ \DeclareUnicodeCharacter{1E90}{\^Z}
+ \DeclareUnicodeCharacter{1E91}{\^z}
+ \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+ \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+ \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+ \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+ \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+ \DeclareUnicodeCharacter{1E97}{\"t}
+ \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+ \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+ \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+ \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+ \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+ \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+ \DeclareUnicodeCharacter{1EBC}{\~E}
+ \DeclareUnicodeCharacter{1EBD}{\~e}
+
+ \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+ \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+ \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+ \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+ \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+ \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+ \DeclareUnicodeCharacter{1EF2}{\`Y}
+ \DeclareUnicodeCharacter{1EF3}{\`y}
+ \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+ \DeclareUnicodeCharacter{1EF8}{\~Y}
+ \DeclareUnicodeCharacter{1EF9}{\~y}
+
+ \DeclareUnicodeCharacter{2013}{--}
+ \DeclareUnicodeCharacter{2014}{---}
+ \DeclareUnicodeCharacter{2018}{\quoteleft}
+ \DeclareUnicodeCharacter{2019}{\quoteright}
+ \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+ \DeclareUnicodeCharacter{201C}{\quotedblleft}
+ \DeclareUnicodeCharacter{201D}{\quotedblright}
+ \DeclareUnicodeCharacter{201E}{\quotedblbase}
+ \DeclareUnicodeCharacter{2022}{\bullet}
+ \DeclareUnicodeCharacter{2026}{\dots}
+ \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+ \DeclareUnicodeCharacter{203A}{\guilsinglright}
+ \DeclareUnicodeCharacter{20AC}{\euro}
+
+ \DeclareUnicodeCharacter{2192}{\expansion}
+ \DeclareUnicodeCharacter{21D2}{\result}
+
+ \DeclareUnicodeCharacter{2212}{\minus}
+ \DeclareUnicodeCharacter{2217}{\point}
+ \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+ \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\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, 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
+ % if we don't reset these, they will remain at "1 true in" of
+ % whatever layout pdftex was dumped with.
+ \pdfhorigin = 1 true in
+ \pdfvorigin = 1 true in
+ \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{607.2pt}{6in}% that's 46 lines
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {-.2in}{0in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
+% 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{673.2pt}{160mm}% that's 51 lines
+ {\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.
+%
+\parseargdef\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\relax
+ \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 \tt
+% (where it can probably be output as-is), 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\_}
+\let\realunder=_
+% 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}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active
+@def@normalbackslash{{@tt@backslashcurfont}}
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+%
+@def@normalturnoffactive{%
+ @let\=@normalbackslash
+ @let"=@normaldoublequote
+ @let~=@normaltilde
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let<=@normalless
+ @let>=@normalgreater
+ @let+=@normalplus
+ @let$=@normaldollar %$ font-lock fix
+ @unsepspaces
+}
+
+% 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 turn back 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 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/docs/version-dev.texi b/docs/version-dev.texi
new file mode 100644
index 0000000..056836e
--- /dev/null
+++ b/docs/version-dev.texi
@@ -0,0 +1,4 @@
+@set UPDATED 13 April 2011
+@set UPDATED-MONTH April 2011
+@set EDITION 1.99
+@set VERSION 1.99
diff --git a/docs/version.texi b/docs/version.texi
new file mode 100644
index 0000000..647f8f7
--- /dev/null
+++ b/docs/version.texi
@@ -0,0 +1,4 @@
+@set UPDATED 14 May 2011
+@set UPDATED-MONTH May 2011
+@set EDITION 1.99
+@set VERSION 1.99