diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/Makefile.am | 62 | ||||
-rw-r--r-- | util/Makefile.in | 882 | ||||
-rw-r--r-- | util/README | 13 | ||||
-rwxr-xr-x | util/bibtex.test | 57 | ||||
-rw-r--r-- | util/defs.in | 364 | ||||
-rw-r--r-- | util/deref.c | 208 | ||||
-rw-r--r-- | util/dir-example | 494 | ||||
-rwxr-xr-x | util/dvipdf.test | 66 | ||||
-rwxr-xr-x | util/fix-info-dir | 317 | ||||
-rwxr-xr-x | util/fixfonts | 84 | ||||
-rw-r--r-- | util/fixref.gawk | 143 | ||||
-rw-r--r-- | util/gdoc | 914 | ||||
-rwxr-xr-x | util/gen-dir-node | 212 | ||||
-rwxr-xr-x | util/gendocs.sh | 351 | ||||
-rw-r--r-- | util/gendocs_template | 100 | ||||
-rwxr-xr-x | util/infosrch | 104 | ||||
-rw-r--r-- | util/install-info-html | 157 | ||||
-rwxr-xr-x | util/latex2html.test | 79 | ||||
-rwxr-xr-x | util/local.test | 59 | ||||
-rw-r--r-- | util/outline.gawk | 144 | ||||
-rwxr-xr-x | util/pdftexi2dvi | 19 | ||||
-rw-r--r-- | util/prepinfo.awk | 355 | ||||
-rwxr-xr-x | util/tex3patch | 70 | ||||
-rw-r--r-- | util/texi-docstring-magic.el | 347 | ||||
-rwxr-xr-x | util/texi2dvi | 1792 | ||||
-rwxr-xr-x | util/texi2dvi.test | 84 | ||||
-rwxr-xr-x | util/texi2pdf | 19 | ||||
-rw-r--r-- | util/texindex.c | 1194 | ||||
-rw-r--r-- | util/texinfo-cat.in | 3 | ||||
-rw-r--r-- | util/texinfo.dtd | 507 | ||||
-rw-r--r-- | util/texinfo.xsl | 242 | ||||
-rwxr-xr-x | util/txitextest | 77 |
32 files changed, 9519 insertions, 0 deletions
diff --git a/util/Makefile.am b/util/Makefile.am new file mode 100644 index 0000000..fec2df9 --- /dev/null +++ b/util/Makefile.am @@ -0,0 +1,62 @@ +# $Id: Makefile.am,v 1.34 2008/03/25 10:51:20 akim Exp $ +# Makefile.am for texinfo/util. +# Run automake in .. to produce Makefile.in from this. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +bin_PROGRAMS = texindex +bin_SCRIPTS = texi2dvi texi2pdf pdftexi2dvi + +# for auctex. +pdftexi2dvi: texi2pdf + cp -f $(srcdir)/texi2pdf $@ + +localedir = $(datadir)/locale +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/gnulib/lib \ + -I$(top_builddir)/gnulib/lib \ + -DLOCALEDIR=\"$(localedir)\" +LDADD = ../lib/libtxi.a $(top_builddir)/gnulib/lib/libgnu.a $(LIBINTL) + +dist_pkgdata_DATA = texinfo.dtd texinfo.xsl +pkgdata_DATA = texinfo.cat + +# we don't actually use version.texi in the rule, but it's one way of +# noticing when the version changes. +texinfo.cat: texinfo-cat.in $(top_srcdir)/doc/version.texi + sed 's/__VERSION__/@VERSION@/g' $(srcdir)/texinfo-cat.in >$@ + +# Most of these are for fun. The only official/installed ones are the +# *texi2* scripts. +# +EXTRA_DIST = README deref.c dir-example fix-info-dir fixfonts \ + fixref.gawk gdoc gen-dir-node gendocs.sh gendocs_template infosrch \ + install-info-html outline.gawk pdftexi2dvi \ + prepinfo.awk tex3patch texi-docstring-magic.el texi2dvi texi2pdf txitextest \ + $(dist_pkgdata_DATA) texinfo-cat.in +CLEANFILES = $(pkgdata_DATA) + + +# Let's not stress people's TeX installations, etc. +if MAINTAINER_MODE +TESTS = \ +bibtex.test \ +dvipdf.test \ +latex2html.test \ +local.test \ +texi2dvi.test + +EXTRA_DIST += $(TESTS) + +# Each test case depends on defs. +check_SCRIPTS = defs +distclean-local: + -rm -rf testSubDir +endif diff --git a/util/Makefile.in b/util/Makefile.in new file mode 100644 index 0000000..fd17739 --- /dev/null +++ b/util/Makefile.in @@ -0,0 +1,882 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 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@ + +# $Id: Makefile.am,v 1.34 2008/03/25 10:51:20 akim Exp $ +# Makefile.am for texinfo/util. +# Run automake in .. to produce Makefile.in from this. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@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@ +bin_PROGRAMS = texindex$(EXEEXT) +@MAINTAINER_MODE_TRUE@am__append_1 = $(TESTS) +subdir = util +DIST_COMMON = README $(dist_pkgdata_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/defs.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/gnulib/m4/alloca.m4 \ + $(top_srcdir)/gnulib/m4/argz.m4 \ + $(top_srcdir)/gnulib/m4/codeset.m4 \ + $(top_srcdir)/gnulib/m4/eealloc.m4 \ + $(top_srcdir)/gnulib/m4/environ.m4 \ + $(top_srcdir)/gnulib/m4/error.m4 \ + $(top_srcdir)/gnulib/m4/exitfail.m4 \ + $(top_srcdir)/gnulib/m4/extensions.m4 \ + $(top_srcdir)/gnulib/m4/getopt.m4 \ + $(top_srcdir)/gnulib/m4/gettext.m4 \ + $(top_srcdir)/gnulib/m4/gettimeofday.m4 \ + $(top_srcdir)/gnulib/m4/glibc21.m4 \ + $(top_srcdir)/gnulib/m4/gnulib-common.m4 \ + $(top_srcdir)/gnulib/m4/gnulib-comp.m4 \ + $(top_srcdir)/gnulib/m4/iconv.m4 \ + $(top_srcdir)/gnulib/m4/include_next.m4 \ + $(top_srcdir)/gnulib/m4/inline.m4 \ + $(top_srcdir)/gnulib/m4/intlmacosx.m4 \ + $(top_srcdir)/gnulib/m4/lib-ld.m4 \ + $(top_srcdir)/gnulib/m4/lib-link.m4 \ + $(top_srcdir)/gnulib/m4/lib-prefix.m4 \ + $(top_srcdir)/gnulib/m4/localcharset.m4 \ + $(top_srcdir)/gnulib/m4/longlong.m4 \ + $(top_srcdir)/gnulib/m4/malloc.m4 \ + $(top_srcdir)/gnulib/m4/malloca.m4 \ + $(top_srcdir)/gnulib/m4/mbchar.m4 \ + $(top_srcdir)/gnulib/m4/mbiter.m4 \ + $(top_srcdir)/gnulib/m4/mbrtowc.m4 \ + $(top_srcdir)/gnulib/m4/mbscasecmp.m4 \ + $(top_srcdir)/gnulib/m4/mbschr.m4 \ + $(top_srcdir)/gnulib/m4/mbslen.m4 \ + $(top_srcdir)/gnulib/m4/mbsncasecmp.m4 \ + $(top_srcdir)/gnulib/m4/mbsstr.m4 \ + $(top_srcdir)/gnulib/m4/mbstate_t.m4 \ + $(top_srcdir)/gnulib/m4/mbswidth.m4 \ + $(top_srcdir)/gnulib/m4/memchr.m4 \ + $(top_srcdir)/gnulib/m4/memcmp.m4 \ + $(top_srcdir)/gnulib/m4/memcpy.m4 \ + $(top_srcdir)/gnulib/m4/memmem.m4 \ + $(top_srcdir)/gnulib/m4/memmove.m4 \ + $(top_srcdir)/gnulib/m4/mempcpy.m4 \ + $(top_srcdir)/gnulib/m4/mkstemp.m4 \ + $(top_srcdir)/gnulib/m4/nls.m4 \ + $(top_srcdir)/gnulib/m4/onceonly.m4 \ + $(top_srcdir)/gnulib/m4/po.m4 \ + $(top_srcdir)/gnulib/m4/progtest.m4 \ + $(top_srcdir)/gnulib/m4/setenv.m4 \ + $(top_srcdir)/gnulib/m4/stdbool.m4 \ + $(top_srcdir)/gnulib/m4/stdint.m4 \ + $(top_srcdir)/gnulib/m4/stdlib_h.m4 \ + $(top_srcdir)/gnulib/m4/stpcpy.m4 \ + $(top_srcdir)/gnulib/m4/strdup.m4 \ + $(top_srcdir)/gnulib/m4/strerror.m4 \ + $(top_srcdir)/gnulib/m4/string_h.m4 \ + $(top_srcdir)/gnulib/m4/strndup.m4 \ + $(top_srcdir)/gnulib/m4/strnlen.m4 \ + $(top_srcdir)/gnulib/m4/sys_stat_h.m4 \ + $(top_srcdir)/gnulib/m4/sys_time_h.m4 \ + $(top_srcdir)/gnulib/m4/tempname.m4 \ + $(top_srcdir)/gnulib/m4/unistd_h.m4 \ + $(top_srcdir)/gnulib/m4/wchar.m4 \ + $(top_srcdir)/gnulib/m4/wchar_t.m4 \ + $(top_srcdir)/gnulib/m4/wctype.m4 \ + $(top_srcdir)/gnulib/m4/wcwidth.m4 \ + $(top_srcdir)/gnulib/m4/wint_t.m4 \ + $(top_srcdir)/gnulib/m4/xalloc.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.h +CONFIG_CLEAN_FILES = defs +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +texindex_SOURCES = texindex.c +texindex_OBJECTS = texindex.$(OBJEXT) +texindex_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +texindex_DEPENDENCIES = ../lib/libtxi.a \ + $(top_builddir)/gnulib/lib/libgnu.a $(am__DEPENDENCIES_1) +binSCRIPT_INSTALL = $(INSTALL_SCRIPT) +SCRIPTS = $(bin_SCRIPTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = texindex.c +DIST_SOURCES = texindex.c +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 = `echo $$p | sed -e 's|^.*/||'`; +dist_pkgdataDATA_INSTALL = $(INSTALL_DATA) +pkgdataDATA_INSTALL = $(INSTALL_DATA) +DATA = $(dist_pkgdata_DATA) $(pkgdata_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +ALLOCA_H = @ALLOCA_H@ +AMTAR = @AMTAR@ +ARGZ_H = @ARGZ_H@ +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@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GETOPT_H = @GETOPT_H@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GLIBC21 = @GLIBC21@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@ +GNULIB_CHOWN = @GNULIB_CHOWN@ +GNULIB_DUP2 = @GNULIB_DUP2@ +GNULIB_ENVIRON = @GNULIB_ENVIRON@ +GNULIB_FCHDIR = @GNULIB_FCHDIR@ +GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@ +GNULIB_GETCWD = @GNULIB_GETCWD@ +GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@ +GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@ +GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@ +GNULIB_LCHOWN = @GNULIB_LCHOWN@ +GNULIB_LSEEK = @GNULIB_LSEEK@ +GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@ +GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@ +GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@ +GNULIB_MBSCHR = @GNULIB_MBSCHR@ +GNULIB_MBSCSPN = @GNULIB_MBSCSPN@ +GNULIB_MBSLEN = @GNULIB_MBSLEN@ +GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@ +GNULIB_MBSNLEN = @GNULIB_MBSNLEN@ +GNULIB_MBSPBRK = @GNULIB_MBSPBRK@ +GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@ +GNULIB_MBSRCHR = @GNULIB_MBSRCHR@ +GNULIB_MBSSEP = @GNULIB_MBSSEP@ +GNULIB_MBSSPN = @GNULIB_MBSSPN@ +GNULIB_MBSSTR = @GNULIB_MBSSTR@ +GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@ +GNULIB_MEMMEM = @GNULIB_MEMMEM@ +GNULIB_MEMPCPY = @GNULIB_MEMPCPY@ +GNULIB_MEMRCHR = @GNULIB_MEMRCHR@ +GNULIB_MKDTEMP = @GNULIB_MKDTEMP@ +GNULIB_MKSTEMP = @GNULIB_MKSTEMP@ +GNULIB_PUTENV = @GNULIB_PUTENV@ +GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@ +GNULIB_READLINK = @GNULIB_READLINK@ +GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@ +GNULIB_RPMATCH = @GNULIB_RPMATCH@ +GNULIB_SETENV = @GNULIB_SETENV@ +GNULIB_SLEEP = @GNULIB_SLEEP@ +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_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_UNSETENV = @GNULIB_UNSETENV@ +GNULIB_WCWIDTH = @GNULIB_WCWIDTH@ +GREP = @GREP@ +HAVE_CALLOC_POSIX = @HAVE_CALLOC_POSIX@ +HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@ +HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@ +HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@ +HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@ +HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@ +HAVE_DECL_STRERROR = @HAVE_DECL_STRERROR@ +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_WCWIDTH = @HAVE_DECL_WCWIDTH@ +HAVE_DUP2 = @HAVE_DUP2@ +HAVE_FTRUNCATE = @HAVE_FTRUNCATE@ +HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@ +HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ +HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +HAVE_LSTAT = @HAVE_LSTAT@ +HAVE_MALLOC_POSIX = @HAVE_MALLOC_POSIX@ +HAVE_MEMPCPY = @HAVE_MEMPCPY@ +HAVE_MKDTEMP = @HAVE_MKDTEMP@ +HAVE_OS_H = @HAVE_OS_H@ +HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@ +HAVE_READLINK = @HAVE_READLINK@ +HAVE_REALLOC_POSIX = @HAVE_REALLOC_POSIX@ +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_STRCASESTR = @HAVE_STRCASESTR@ +HAVE_STRCHRNUL = @HAVE_STRCHRNUL@ +HAVE_STRNDUP = @HAVE_STRNDUP@ +HAVE_STRPBRK = @HAVE_STRPBRK@ +HAVE_STRSEP = @HAVE_STRSEP@ +HAVE_STRTOD = @HAVE_STRTOD@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ +HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +HAVE_UNISTD_H = @HAVE_UNISTD_H@ +HAVE_UNSETENV = @HAVE_UNSETENV@ +HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +HAVE_WCHAR_H = @HAVE_WCHAR_H@ +HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ +HAVE_WINT_T = @HAVE_WINT_T@ +HAVE__BOOL = @HAVE__BOOL@ +HELP2MAN = @HELP2MAN@ +HEVEA = @HEVEA@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +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@ +LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEXT_STDINT_H = @NEXT_STDINT_H@ +NEXT_STDLIB_H = @NEXT_STDLIB_H@ +NEXT_STRING_H = @NEXT_STRING_H@ +NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@ +NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ +NEXT_UNISTD_H = @NEXT_UNISTD_H@ +NEXT_WCHAR_H = @NEXT_WCHAR_H@ +NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSUB = @POSUB@ +PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +RANLIB = @RANLIB@ +REPLACE_CHOWN = @REPLACE_CHOWN@ +REPLACE_FCHDIR = @REPLACE_FCHDIR@ +REPLACE_GETCWD = @REPLACE_GETCWD@ +REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +REPLACE_LCHOWN = @REPLACE_LCHOWN@ +REPLACE_LSEEK = @REPLACE_LSEEK@ +REPLACE_MEMMEM = @REPLACE_MEMMEM@ +REPLACE_MKDIR = @REPLACE_MKDIR@ +REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ +REPLACE_PUTENV = @REPLACE_PUTENV@ +REPLACE_STRCASESTR = @REPLACE_STRCASESTR@ +REPLACE_STRERROR = @REPLACE_STRERROR@ +REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@ +REPLACE_STRSTR = @REPLACE_STRSTR@ +REPLACE_STRTOD = @REPLACE_STRTOD@ +REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +STDBOOL_H = @STDBOOL_H@ +STDINT_H = @STDINT_H@ +STRIP = @STRIP@ +SYS_STAT_H = @SYS_STAT_H@ +SYS_TIME_H = @SYS_TIME_H@ +TERMLIBS = @TERMLIBS@ +TEX = @TEX@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +VOID_UNSETENV = @VOID_UNSETENV@ +WCHAR_H = @WCHAR_H@ +WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +WCTYPE_H = @WCTYPE_H@ +WINT_T_SUFFIX = @WINT_T_SUFFIX@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +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@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +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@ +exec_prefix = @exec_prefix@ +gl_LIBOBJS = @gl_LIBOBJS@ +gl_LTLIBOBJS = @gl_LTLIBOBJS@ +gltests_LIBOBJS = @gltests_LIBOBJS@ +gltests_LTLIBOBJS = @gltests_LTLIBOBJS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +native_tools = @native_tools@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +bin_SCRIPTS = texi2dvi texi2pdf pdftexi2dvi +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/gnulib/lib \ + -I$(top_builddir)/gnulib/lib \ + -DLOCALEDIR=\"$(localedir)\" + +LDADD = ../lib/libtxi.a $(top_builddir)/gnulib/lib/libgnu.a $(LIBINTL) +dist_pkgdata_DATA = texinfo.dtd texinfo.xsl +pkgdata_DATA = texinfo.cat + +# Most of these are for fun. The only official/installed ones are the +# *texi2* scripts. +# +EXTRA_DIST = README deref.c dir-example fix-info-dir fixfonts \ + fixref.gawk gdoc gen-dir-node gendocs.sh gendocs_template \ + infosrch install-info-html outline.gawk pdftexi2dvi \ + prepinfo.awk tex3patch texi-docstring-magic.el texi2dvi \ + texi2pdf txitextest $(dist_pkgdata_DATA) texinfo-cat.in \ + $(am__append_1) +CLEANFILES = $(pkgdata_DATA) + +# Let's not stress people's TeX installations, etc. +@MAINTAINER_MODE_TRUE@TESTS = \ +@MAINTAINER_MODE_TRUE@bibtex.test \ +@MAINTAINER_MODE_TRUE@dvipdf.test \ +@MAINTAINER_MODE_TRUE@latex2html.test \ +@MAINTAINER_MODE_TRUE@local.test \ +@MAINTAINER_MODE_TRUE@texi2dvi.test + + +# Each test case depends on defs. +@MAINTAINER_MODE_TRUE@check_SCRIPTS = defs +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu util/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu util/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: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +defs: $(top_builddir)/config.status $(srcdir)/defs.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +texindex$(EXEEXT): $(texindex_OBJECTS) $(texindex_DEPENDENCIES) + @rm -f texindex$(EXEEXT) + $(LINK) $(texindex_OBJECTS) $(texindex_LDADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f $$d$$p; then \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ + else :; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texindex.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +install-dist_pkgdataDATA: $(dist_pkgdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" + @list='$(dist_pkgdata_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(dist_pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \ + $(dist_pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \ + done + +uninstall-dist_pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_pkgdata_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \ + done +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" + @list='$(pkgdata_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \ + $(pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *$$ws$$tst$$ws*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *$$ws$$tst$$ws*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +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 $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)"; 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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +@MAINTAINER_MODE_FALSE@distclean-local: +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-local distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-dist_pkgdataDATA install-pkgdataDATA + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS install-binSCRIPTS + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-dist_pkgdataDATA uninstall-pkgdataDATA + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-binPROGRAMS clean-generic ctags distclean \ + distclean-compile distclean-generic distclean-local \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-binSCRIPTS \ + install-data install-data-am install-dist_pkgdataDATA \ + 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-pkgdataDATA \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-dist_pkgdataDATA uninstall-pkgdataDATA + + +# for auctex. +pdftexi2dvi: texi2pdf + cp -f $(srcdir)/texi2pdf $@ + +# we don't actually use version.texi in the rule, but it's one way of +# noticing when the version changes. +texinfo.cat: texinfo-cat.in $(top_srcdir)/doc/version.texi + sed 's/__VERSION__/@VERSION@/g' $(srcdir)/texinfo-cat.in >$@ +@MAINTAINER_MODE_TRUE@distclean-local: +@MAINTAINER_MODE_TRUE@ -rm -rf testSubDir +# 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/util/README b/util/README new file mode 100644 index 0000000..8ed7b07 --- /dev/null +++ b/util/README @@ -0,0 +1,13 @@ +$Id: README,v 1.6 2008/01/02 01:36:32 karl Exp $ +texinfo/util/README + + Copyright (C) 2002, 2008 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + +Assorted Texinfo-related files. + +texindex, texi2dvi, texi2pdf, pdftexi2dvi, and the XML stuff get installed. +The other items here are for your amusement and/or hacking pleasure. diff --git a/util/bibtex.test b/util/bibtex.test new file mode 100755 index 0000000..0bb29a0 --- /dev/null +++ b/util/bibtex.test @@ -0,0 +1,57 @@ +#! /bin/sh +# Copyright (C) 2006, 2007 Free Software Foundation, Inc. +# +# This file is part of GNU Texinfo. +# +# GNU Texinfo 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. +# +# GNU Texinfo 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/>. + +required='hevea' + +. ./defs || exit 1 + +set -e + +create_input_tex <<EOF +\cite{texinfo.doc} +\bibliographystyle{plain} +\bibliography{sample} +EOF + +cat >sample.bib <<EOF +@misc{texinfo.doc, + title = "{GNU Texinfo}: The {GNU} documentation format", + author = "Robert J. Chassell and Richard M. Stallman", + year = "1988" +} +EOF + + +# check HTML|INFO|TEXT|DVI|PDF +# ---------------------------- +check () +{ + out=$1 + # Testing the local build mode. + TEXI2DVI_pass --$out --batch --tidy input.tex + # There should only be the DVI and the TEXI file. + assert_files input.$out input.tex sample.bib input.t2d + cp input.$out /tmp/foo + rm input.$out +} + +# Currently we don't use bibtex with hevea. This is to be fixed. +for out in dvi pdf # html info text +do + check $out +done diff --git a/util/defs.in b/util/defs.in new file mode 100644 index 0000000..f70b1e7 --- /dev/null +++ b/util/defs.in @@ -0,0 +1,364 @@ +# -*- shell-script -*- +# @configure_input@ +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# (This file was originally part of GNU Automake.) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Defines for Automake testing environment. +# Tom Tromey <tromey@cygnus.com> + +# Be Bourne compatible. +# (Snippet copied from configure's initialization in Autoconf 2.57.) +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Ensure we are running from the right directory. +test -f ./defs || { + echo "defs: not found in current directory" 1>&2 + exit 1 +} + +# If srcdir is not set, then we are not running from `make check', be verbose. +if test -z "$srcdir"; then + VERBOSE=x + # compute $srcdir. + srcdir=`echo "$0" | sed -e 's,/[^\\/]*$,,'` + test $srcdir = $0 && srcdir=. +fi + +# Ensure $srcdir is set correctly. +test -f $srcdir/defs.in || { + echo "$srcdir/defs.in not found, check \$srcdir" 1>&2 + exit 1 +} + +me=`echo "$0" | sed -e 's,.*[\\/],,;s/\.test$//'` + +# See how redirections should work. User can set VERBOSE to see all +# output. +test -z "$VERBOSE" && { + exec > /dev/null 2>&1 +} + +# Make sure we override the user shell. +SHELL='@SHELL@' +export SHELL + +srcdir_abs=`cd $srcdir && pwd` +test -z "$TEXI2DVI" && TEXI2DVI=$srcdir_abs/texi2dvi + +# be sure we use texi2dvi and texindex from our own directory, not +# whatever happens to be in the path. +echo "defs: prepending $srcdir_abs to PATH for testing." +PATH="@abs_builddir@:@abs_srcdir@:$PATH" + +# Some shells forget to export modified environment variables. +# (See note about `export' in the Autoconf manual.) +export PATH + +# User can override various tools used. +test -z "$PERL" && PERL='@PERL@' + +if test -n "$required" +then + for tool in $required + do + # Check that each required tool is present. + case $tool in + hevea) + # HeVeA supports -version only. Use configure to find it. + test -n "@HEVEA@" || exit 77 + ;; + tex) + # No all versions of Tex support `--version', so we use + # a configure check. + test -n "@TEX@" || exit 77 + ;; + # Generic case: the tool must support --version. + *) + echo "$me: running $tool --version" + ( $tool --version ) || exit 77 + ;; + esac + done +fi + + +# Always use an absolute srcdir. Otherwise symlinks made in subdirs +# of the test dir just won't work. +case "$srcdir" in + [\\/]* | ?:[\\/]*) + ;; + + *) + srcdir=`CDPATH=: && cd "$srcdir" && pwd` + ;; +esac + +chmod -R a+rwx testSubDir > /dev/null 2>&1 +rm -rf testSubDir > /dev/null 2>&1 +mkdir testSubDir + +# Copy in some files we need. +cp $srcdir/../doc/texinfo.tex testSubDir || exit 1 + +cd ./testSubDir + + +# Unset the user's envvars that might change the behavior. +unset TEXI2DVI_BUILD_MODE +unset TEXI2DVI_BUILD_DIRECTORY + +echo "=== Running test $0" + +# POSIX no longer requires 'egrep' and 'fgrep', +# but some hosts lack 'grep -E' and 'grep -F'. +EGREP='@EGREP@' +FGREP='@FGREP@' + +# The amount we should wait after modifying files depends on the platform. +# For instance, Windows '95, '98 and ME have 2-second granularity +# and can be up to 3 seconds in the future w.r.t. the system clock. +sleep='sleep @MODIFICATION_DELAY@' + +# The tests call `make -e' but we do not want $srcdir from the environment +# to override the definition from the Makefile. +testsrcdir=$srcdir +unset srcdir + + +# create_input_texi < INPUT +# ------------------------- +# Create input.texi adding stdin inside a default prologue/epilogue +create_input_texi () +{ + { + cat << END +\input texinfo @c -*-texinfo-*- +@setfilename input +@settitle input + +@ifnottex +@node Top +@top input +@end ifnottex + +END + cat + cat << END +@bye +END + } >input.texi +} + + +# create_input_tex < INPUT +# ------------------------ +# Create input.tex adding stdin inside a default prologue/epilogue +create_input_tex () +{ + { + cat << END +\documentclass{article} + +\begin{document} +END + cat + cat << END +\end{document} +END + } >input.tex +} + + +# TEXI2DVI_run status [options...] +# -------------------------------- +# Run texi2dvi with OPTIONS, and fail if does not exit with STATUS. +TEXI2DVI_run () +{ + expected_exitcode=$1 + shift + exitcode=0 + if test -n "$VERBOSE"; then + set x --debug --verbose ${1+"$@"} + shift + fi + texi2dvi ${1+"$@"} 2>stderr >stdout || exitcode=$? + cat stderr + cat stdout + test $exitcode = $expected_exitcode || exit 1 +} + + +# TEXI2DVI_fail [options...] +# --------------------------- +# Run texi2dvi with OPTIONS, and fail if does not exit with failure. +TEXI2DVI_fail () +{ + TEXI2DVI_run 1 ${1+"$@"} +} + + +# TEXI2DVI_pass [options...] +# --------------------------- +# Run texi2dvi with OPTIONS, and fail if does not exit with failure. +TEXI2DVI_pass () +{ + TEXI2DVI_run 0 ${1+"$@"} +} + + +# optionset_get N OPTIONSET<1> -- OPTIONSET<2> -- ... +# --------------------------------------------------- +# Return OPTIONSET<N> +optionset_get () +{ + n=$1 + shift + # Find the optionset. + while test $n != 1; do + case $1 in + --) n=`expr $n - 1`;; + esac + shift + done + # Return the optionset. + while true; do + case $#:$1 in + 0:) break;; + *:--) shift; break;; + *) echo "$1"; shift;; + esac + done +} + +# list_files () +# ------------- +# Return the sorted list of files in this directory, except the "invisible" ones. +list_files () +{ + for f in * + do + case $f in + texinfo.tex | stdout | stderr | ls.expected | ls.value );; + *) echo $f;; + esac + done | sort +} + + +# assert_files (EXPECTED-FILES) +# ----------------------------- +# Only those files are valid in the current directory. +assert_files () +{ + if test -n "$VERBOSE"; then + ls + fi + list_files > ls.value + echo "$*" | tr ' ' '\n' | sort > ls.expected + diff -u ls.expected ls.value +} + + +# assert_and_remove_files (EXPECTED-FILES) +# ---------------------------------------- +# Only those files are valid in the current directory. Remove them +# afterwards. +assert_and_remove_files () +{ + assert_files "$@" + rm -rf "$@" +} + + +# title TITLE... +# -------------- +# Make a huge title to ease the reading of the output. +title () +{ + ( + set +x + echo " $@ " | sed -e 's/./=/g' + echo " $@ " + echo " $@ " | sed -e 's/./=/g' + ) +} + +# $latex_paragraph +# ---------------- +# Some lengthy LaTeX. +# grep -E '^[a-zA-Z]+$' /usr/share/dict/words | sed 200q | pr --page-width=76 --column=5 --omit-header +latex_paragraph=' +A Acrux Aegean Ahmad Albany +AOL Actaeon Aelfric Ahmadabad Albee +Aachen Acton Aeneas Ahmed Alberio +Aaliyah Acts Aeneid Ahriman Albert +Aaron Acuff Aeolus Aida Alberta +Abbas Ada Aeroflot Aiken Alberto +Abbasid Adam Aeschylus Aileen Albigensian +Abbott Adams Aesculapius Aimee Albion +Abby Adan Aesop Ainu Albireo +Abdul Adana Afghan Airedale Albuquerque +Abe Adar Afghanistan Airedales Alcatraz +Abel Addams Afghans Aisha Alcestis +Abelard Adderley Africa Ajax Alcibiades +Abelson Addie African Akbar Alcmena +Aberdeen Addison Africans Akhmatova Alcoa +Abernathy Adela Afrikaans Akihito Alcott +Abidjan Adelaide Afrikaner Akita Alcuin +Abigail Adele Afrikaners Akkad Alcyone +Abilene Adeline Afro Akron Aldan +Abner Aden Afrocentrism Al Aldebaran +Abraham Adenauer Afros Ala Alden +Abram Adhara Ag Alabama Alderamin +Abrams Adidas Agamemnon Alabaman Aldo +Absalom Adirondack Agassi Alabamans Aldrin +Abuja Adirondacks Agassiz Alabamian Alec +Abyssinia Adkins Agatha Alabamians Aleichem +Abyssinian Adler Aggie Aladdin Alejandra +Ac Adolf Aglaia Alamo Alejandro +Acadia Adolfo Agnes Alamogordo Alembert +Acapulco Adolph Agnew Alan Aleppo +Accra Adonis Agni Alana Aleut +Acevedo Adonises Agra Alar Aleutian +Achaean Adrian Agricola Alaric Alex +Achebe Adriana Agrippa Alaska Alexander +Achernar Adriatic Agrippina Alaskan Alexandra +Acheson Adrienne Aguilar Alaskans Alexandria +Achilles Advent Aguinaldo Alba Alexei +Aconcagua Adventist Aguirre Albania Alexis +Acosta Advents Agustin Albanian Alfonso +Acropolis Advil Ahab Albanians Alfonzo +' + + +# Turn on shell traces when VERBOSE is set. +if test -n "$VERBOSE"; then + set -x +else + : +fi +pwd diff --git a/util/deref.c b/util/deref.c new file mode 100644 index 0000000..98e8ce0 --- /dev/null +++ b/util/deref.c @@ -0,0 +1,208 @@ +/* + * deref.c + * + * Make all texinfo references into the one argument form. + * + * Arnold Robbins + * arnold@gnu.org + * Written: December, 1991 + * Released: November, 1998 + * + * Copyright 1991, 1998 Arnold David Robbins + * + * DEREF is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DEREF is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * LIMITATIONS: + * One texinfo cross reference per line. + * Cross references may not cross newlines. + * Use of fgets for input (to be fixed). + */ + +#include <stdio.h> +#include <ctype.h> +#include <errno.h> + +/* for gcc on the 3B1, delete if this gives you grief */ +extern int fclose(FILE *fp); +extern int fprintf(FILE *fp, const char *str, ...); +/* extern int sprintf(char *str, const char *fmt, ...); */ +extern int fputs(char *buf, FILE *fp); + +extern char *strerror(int errno); +extern char *strchr(char *cp, int ch); +extern int strncmp(const char *s1, const char *s2, int count); + +extern int errno; + +void process(FILE *fp); +void repair(char *line, char *ref, int toffset); + +int Errs = 0; +char *Name = "stdin"; +int Line = 0; +char *Me; + +/* main --- handle arguments, global vars for errors */ + +int +main(int argc, char **argv) +{ + FILE *fp; + + Me = argv[0]; + + if (argc == 1) + process(stdin); + else + for (argc--, argv++; *argv != NULL; argc--, argv++) { + if (argv[0][0] == '-' && argv[0][1] == '\0') { + Name = "stdin"; + Line = 0; + process(stdin); + } else if ((fp = fopen(*argv, "r")) != NULL) { + Name = *argv; + Line = 0; + process(fp); + fclose(fp); + } else { + fprintf(stderr, "%s: can not open: %s\n", + *argv, strerror(errno)); + Errs++; + } + } + return Errs != 0; +} + +/* isref --- decide if we've seen a texinfo cross reference */ + +int +isref(char *cp) +{ + if (strncmp(cp, "@ref{", 5) == 0) + return 5; + if (strncmp(cp, "@xref{", 6) == 0) + return 6; + if (strncmp(cp, "@pxref{", 7) == 0) + return 7; + return 0; +} + +/* process --- read files, look for references, fix them up */ + +void +process(FILE *fp) +{ + char buf[BUFSIZ]; + char *cp; + int count; + + while (fgets(buf, sizeof buf, fp) != NULL) { + Line++; + cp = strchr(buf, '@'); + if (cp == NULL) { + fputs(buf, stdout); + continue; + } + do { + count = isref(cp); + if (count == 0) { + cp++; + cp = strchr(cp, '@'); + if (cp == NULL) { + fputs(buf, stdout); + goto next; + } + continue; + } + /* got one */ + repair(buf, cp, count); + break; + } while (cp != NULL); + next: ; + } +} + +/* repair --- turn all texinfo cross references into the one argument form */ + +void +repair(char *line, char *ref, int toffset) +{ + int braces = 1; /* have seen first left brace */ + char *cp; + + ref += toffset; + + /* output line up to and including left brace in reference */ + for (cp = line; cp <= ref; cp++) + putchar(*cp); + + /* output node name */ + for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++) + putchar(*cp); + + if (*cp != '}') { /* could have been one arg xref */ + /* skip to matching right brace */ + for (; braces > 0; cp++) { + switch (*cp) { + case '@': + cp++; /* blindly skip next character */ + break; + case '{': + braces++; + break; + case '}': + braces--; + break; + case '\n': + case '\0': + Errs++; + fprintf(stderr, + "%s: %s: %d: mismatched braces\n", + Me, Name, Line); + goto out; + default: + break; + } + } + out: + ; + } + + putchar('}'); + if (*cp == '}') + cp++; + + /* now the rest of the line */ + for (; *cp; cp++) + putchar(*cp); + return; +} + +/* strerror --- return error string, delete if in your library */ + +char * +strerror(int errno) +{ + static char buf[100]; + extern int sys_nerr; + extern char *sys_errlist[]; + + if (errno < sys_nerr && errno >= 0) + return sys_errlist[errno]; + + sprintf(buf, "unknown error %d", errno); + return buf; +} diff --git a/util/dir-example b/util/dir-example new file mode 100644 index 0000000..eac9490 --- /dev/null +++ b/util/dir-example @@ -0,0 +1,494 @@ +This is the directory file `dir' a.k.a. `DIR', which contains the + topmost node of the Info hierarchy. +This particular dir file is merely made available for your hacking + pleasure, not official or standard in any way. If it doesn't make sense + to you, or you don't like it, ignore it. +rms suggested that we follow the categories of the Free Software + Directory (http://www.gnu.org/directory/) where possible. Since + capitalization in the directory is random, I've chosen to use + `minimum' capitals, just the first word and proper nouns. +If you have dir entries for Texinfo manuals you'd like to be added here, + please send them to karl@gnu.org. + +$Id: dir-example,v 1.77 2008/03/25 15:09:14 karl Exp $ + +File: dir, Node: Top, This is the top of the INFO tree. + +This is the Info main menu (aka directory node). +A few useful Info commands: + + `q' quits; + `?' lists all Info commands; + `h' starts the Info tutorial; + `mTexinfo RET' visits the Texinfo manual, etc. + +Not all of the topics shown below may be available on this system. + +* Menu: + +Basics +* Bash: (bash). The GNU Bourne-Again SHell. +* BC: (bc). Arbitrary precision calculator language. +* Common options: (coreutils)Common options. Common options. +* Coreutils: (coreutils). Core GNU (file, text, shell) utilities. +* DC: (dc). Postfix desk calculator. +* Date input formats: (coreutils)Date input formats. +* Ed: (ed). The GNU line editor. +* File permissions: (coreutils)File permissions. Access modes. +* Finding files: (find). Operating on files matching certain criteria. +* Gcal: (gcal). GNU calendar program. +* Hello: (hello). Hello, GNU world. +* Time: (time). Measuring program resource usage. + +Text creation and manipulation +* Diffutils: (diff). Comparing and merging files. +* Gawk: (gawk). A text scanning and processing language. +* M4: (m4). A powerful macro processor. +* grep: (grep). Print lines matching a pattern. +* sed: (sed). Stream EDitor. +* Wdiff: (wdiff). Word difference finder and related tools. + +Texinfo documentation system +* Info: (info). Documentation browsing system. +* Texi2HTML: (texi2html). Texinfo to HTML Converter. +* Texinfo: (texinfo). The GNU documentation format. +* info standalone: (info-stnd). Standalone Info reader. +* infokey: (info-stnd)Invoking infokey. Compile Info customizations. +* install-info: (texinfo)Invoking install-info. Updating info/dir entries. +* makeinfo: (texinfo)Creating an Info File. Translate Texinfo source. +* texi2dvi: (texinfo)Format with texi2dvi. Printing Texinfo documentation. +* texindex: (texinfo)Format with tex/texindex. Sorting Texinfo index files. + +Archiving +* Cpio: (cpio). Copy-in-copy-out archiver to tape or disk. +* Shar utilities: (sharutils). Shell archiver, uuencode/uudecode. +* Tar: (tar). Making tape (or disk) archives. + +Compression +* bzip2: (bzip2). General (de)compression of files (blocksort). +* Gzip: (gzip). General (de)compression of files (lzw). + +Email +* Anubis: (anubis). The GNU outgoing mail processor. +* Mailutils: (mailutils). Utilities & library for mailboxes, protocols. + +Network applications +* Gawkinet: (gawkinet). TCP/IP Internetworking With `gawk'. +* Wget: (wget). Non-interactive network downloader. + +Printing Tools +* PreScript: (a2ps) PreScript. Input language for a2ps +* a2ps: (a2ps). PostScript Generating Utility +* card: (a2ps) card. Print Reference Cards +* fixnt: (a2ps) fixnt. Fixing Microsoft NT PostScript Files +* fixps: (a2ps) fixps. Fixing Some Ill Designed PostScript Files +* ogonkify: (ogonkify). Ogonkify +* pdiff: (a2ps) pdiff. Produce Pretty Comparison of Files +* psmandup: (a2ps) psmandup. Printing Duplex on Simplex Printers +* psset: (a2ps) psset. Inserting calls to setpagedevice + +Software development +* As: (as). Assembler. +* Autoconf: (autoconf). Create source code configuration scripts. +* Automake: (automake). Making GNU standards-compliant Makefiles. +* Binutils: (binutils). The GNU binary utilities. +* Cpp: (cpp). The GNU C preprocessor. +* Cpplib: (cppinternals). Cpplib internals. +* CVS: (cvs). Concurrent Versions System +* DejaGnu: (dejagnu). Testing framework. +* Dmalloc: (dmalloc). Malloc debug library. +* Gdb: (gdb). The GNU debugger. +* bison: (bison). GNU parser generator (Yacc replacement). +* egcs: (egcs). Experimental GNU C compiler. +* Flex: (flex). A fast scanner generator. +* g77: (g77). GNU Fortran 77 compiler. +* Gasp: (gasp). GNU Assembler preprocessor. +* gcc: (gcc). The GNU Compiler Collection. +* gccinstall: (gccinstall). Installing the GNU Compiler Collection. +* gccint: (gccint). Internals of the GNU Compiler Collection. +* Gnats: (gnats). Cygnus bug tracking system. +* Gnulib: (gnulib). Source files to share among distributions. +* Gperf: (gperf). Perfect hash function generator. +* Gprof: (gprof). Profiler. +* Guile Reference: (guile). The Guile reference manual. +* Guile Tutorial: (guile-tut). The Guile Tutorial. +* ID database: (id-utils). Identifier database utilities. +* Indent: (indent). Prettyprinter for programs. +* Ld: (ld). Linker. +* Libtool: (libtool). Generic library support script. +* Make: (make). Remake files automatically. +* Remsync: (remsync). Remote synchronization of directory trees. +* Send PR: (send-pr). Cygnus bug reporting for Gnats. +* Source config: (cfg-paper). Some theory on configuring source packages. +* help2man: (help2man). Automatic manual page generation from -help. + +Emacs +* Ada mode: (ada-mode). The GNU Emacs mode for editing Ada. +* Autotype: (autotype). Convenient features for text that you enter frequently + in Emacs. +* CC Mode: (ccmode). Emacs mode for editing C, C++, Objective-C, + Java, Pike, and IDL code. +* CL: (cl). Partial Common Lisp support for Emacs Lisp. +* Dired-X: (dired-x). Dired Extra Features. +* EUDC: (eudc). A client for directory servers (LDAP, PH) +* Ebrowse: (ebrowse). A C++ class browser for Emacs. +* Ediff: (ediff). A visual interface for comparing and merging programs. +* Emacs: (emacs). The extensible self-documenting text editor. +* Elisp: (elisp). The Emacs Lisp Reference Manual. +* Emacs FAQ: (efaq). Frequently Asked Questions about Emacs. +* Emacs MIME: (emacs-mime). The MIME de/composition library. +* Eshell: (eshell). A command shell implemented in Emacs Lisp. +* Forms: (forms). Emacs package for editing data bases + by filling in forms. +* Gnus: (gnus). The newsreader Gnus. +* IDLWAVE: (idlwave). Major mode and shell for IDL and WAVE/CL files. +* Intro Elisp: (emacs-lisp-intro). Introduction to Elisp programming. + +* AUC TeX: (auctex). Editing (La)TeX files. +* MH-E: (mh-e). Emacs interface to the MH mail system. +* Message: (message). Mail and news composition mode that goes with Gnus. +* PCL-CVS: (pcl-cvs). Emacs front-end to CVS. +* RefTeX: (reftex). Emacs support for LaTeX cross-references and citations. +* SC: (sc). Supercite lets you cite parts of messages you're + replying to, in flexible ways. +* Speedbar: (speedbar). File/Tag summarizing utility. +* TRAMP: (tramp). Transparent Remote Access, Multiple Protocol + Emacs remote file access via rsh and rcp. +* VIP: (vip). An older VI-emulation for Emacs. +* VIPER: (viper). The newest Emacs VI-emulation mode. + (also, A VI Plan for Emacs Rescue or the VI PERil.) +* VM: (vm). View Mail for Emacs. +* Widget: (widget). Documenting the "widget" package used by the + Emacs Custom facility. +* WoMan: (woman). Browse UN*X Manual Pages `Wo (without) Man'. + +Typesetting +* Font utilities: (fontu). Programs for font manipulation. +* Groff: (groff). The GNU troff document formatting system. +* GV: (gv). The GNU PostScript and PDF viewer. + +GNU Gettext Utilities +* ISO3166: (gettext)Country Codes. ISO 3166 country codes. +* ISO639: (gettext)Language Codes. ISO 639 language codes. +* autopoint: (gettext)autopoint Invocation. Copy gettext infrastructure. +* envsubst: (gettext)envsubst Invocation. Expand environment variables. +* gettext: (gettext). GNU gettext utilities. +* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext. +* msgattrib: (gettext)msgattrib Invocation. Select part of a PO file. +* msgcat: (gettext)msgcat Invocation. Combine several PO files. +* msgcmp: (gettext)msgcmp Invocation. Compare a PO file and template. +* msgcomm: (gettext)msgcomm Invocation. Match two PO files. +* msgconv: (gettext)msgconv Invocation. Convert PO file to encoding. +* msgen: (gettext)msgen Invocation. Create an English PO file. +* msgexec: (gettext)msgexec Invocation. Process a PO file. +* msgfilter: (gettext)msgfilter Invocation. Pipe a PO file through a filter. +* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files. +* msggrep: (gettext)msggrep Invocation. Select part of a PO file. +* msginit: (gettext)msginit Invocation. Create a fresh PO file. +* msgmerge: (gettext)msgmerge Invocation. Update a PO file from template. +* msgunfmt: (gettext)msgunfmt Invocation. Uncompile MO file into PO file. +* msguniq: (gettext)msguniq Invocation. Unify duplicates for PO file. +* ngettext: (gettext)ngettext Invocation. Translate a message with plural. +* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file. + +Software libraries +* Annotate: (annotate). High-level GDB to GUI's. +* Bfd: (bfd). The Binary File Descriptor library. +* Gdb-Internals: (gdbint). The GNU debugger's internals. +* GDB library: (libgdb). Application programming interface to GDB. +* GDBM: (gdbm). Hashed databases. +* GDK: (gdk). General drawing kit. +* GTK: (gtk). GIMP toolkit. +* History: (history). Recall previous lines of input. +* Ld internals: (ldint). GNU linker internals. +* Libc: (libc). C library. +* Mmalloc: (mmalloc). The GNU mapped-malloc package. +* Stabs: (stabs). The "stabs" debugging information format. +* Readline: (readline). General command-line interface. +* Termcap: (termcap). All about /etc/termcap. + +C++ libraries +* Iostream: (iostream). C++ input/output. +* autosprintf: (autosprintf). Support for printf format strings in C++. + +GNU organization +* Maintain: (maintain). GNU maintainer guidelines. +* Maintaining Findutils: (find-maint). Maintaining GNU findutils. +* Standards: (standards). GNU coding standards. + +GNU music project +* LilyPond: (lilypond). The GNU music typesetter. +* LilyPond internals: (lilypond-internals). LilyPond internals. +* ly2dvi: (lilypond)Invoking ly2dvi:: Titling LilyPond scores. +* convert-ly: (lilypond)Invoking convert-ly:: Older LilyPond versions. +* midi2ly: (lilypond)Invoking midi2ly:: Importing MIDI. +* etf2ly: (lilypond)Invoking etf2ly:: Importing Finale. +* abc2ly: (lilypond)Invoking abc2ly:: Importing ABC. +* pmx2ly: (lilypond)Invoking pmx2ly:: Importing PMX. +* musedata2ly: (lilypond)Invoking musedata2ly::Importing Musedata. +* mup2ly: (lilypond)Invoking mup2ly:: Importing MUP. + +TeX +* Afm2tfm: (dvips)Invoking afm2tfm. Making Type 1 fonts available to TeX. +* Dvips: (dvips). DVI-to-PostScript translator. +* DVI-to-PNG: (dvipng). DVI to Portable Network Graphics (PNG). +* Eplain: (eplain). Expanding on plain TeX. +* Kpathsearch: (kpathsea). File lookup along search paths. +* LaTeX: (latex2e). LaTeX2e. +* MakeIndex: (makeindex). Index creation for TeX. +* Naming TeX fonts: (fontname). Filenames for TeX fonts. +* TDS: (tds). Standard TeX directory structure. +* TeXDraw: (texdraw). Drawing PostScript diagrams within TeX. +* Web2c: (web2c). TeX, Metafont, and their companion programs. + +DOS +* GNUish: (gnuish). GNU utilities for DOS. +* Mtools: (mtools). Access DOS disks from Unix. + +Science +* R FAQ: (R-FAQ). The R statistical language FAQ. + +Other things +* Jargon: (jargon). The jargon file. +* Netpbm: (netpbm). Images/graphics manipulation programs. +* JED: (jed). JED editor documentation. +* Octave: (octave). Octave - A language for numerical computation. +* PRCS: (prcs). Project revision control system. +* Screen: (screen). Terminal multiplexer. + +Individual utilities +* aclocal: (automake)Invoking aclocal. Generating aclocal.m4. +* addr2line: (binutils)addr2line. Convert addresses to file and line. +* ar: (binutils)ar. Create, modify, and extract from archives. +* at-pr: (gnats)at-pr. Bug report timely reminders. +* autoconf: (autoconf)autoconf Invocation. How to create configuration scripts. +* autoheader: (autoconf)autoheader Invocation. How to create configuration templates +* autom4te: (autoconf)autom4te Invocation. The Autoconf executables backbone. +* automake: (automake)Invoking Automake. Generating Makefile.in. +* autoreconf: (autoconf)autoreconf Invocation. Remaking multiple `configure' scripts +* autoscan: (autoconf)autoscan Invocation. Semi-automatic `configure.ac' writing +* autoupdate: (autoconf)autoupdate Invocation. Automatic update of `configure.ac' +* awk: (gawk)Invoking gawk. Text scanning and processing. +* base64: (coreutils)base64 invocation. Base64 encode/decode data. +* basename: (coreutils)basename invocation. Strip directory and suffix. +* bibtex: (web2c)BibTeX invocation. Maintaining bibliographies. +* c++filt: (binutils)c++filt. Filter to demangle encoded C++ symbols. +* cat: (coreutils)cat invocation. Concatenate and write files. +* chgrp: (coreutils)chgrp invocation. Change file groups. +* chmod: (coreutils)chmod invocation. Change file permissions. +* chown: (coreutils)chown invocation. Change file owners/groups. +* chroot: (coreutils)chroot invocation. Specify the root directory. +* cksum: (coreutils)cksum invocation. Print POSIX CRC checksum. +* cmp: (diff)Invoking cmp. Compare 2 files byte by byte. +* comm: (coreutils)comm invocation. Compare sorted files by line. +* comsatd: (mailutils)comsatd. Comsat daemon. +* config.status: (autoconf)config.status Invocation. Recreating configurations. +* configure: (autoconf)configure Invocation. Configuring a package. +* cp: (coreutils)cp invocation. Copy files. +* csplit: (coreutils)csplit invocation. Split by context. +* cut: (coreutils)cut invocation. Print selected parts of lines. +* cvs: (cvs)CVS commands. Concurrent Versions System +* cvsclient: (cvsclient). The CVS client/server protocol. +* cxxfilt: (binutils)c++filt. MS-DOS name for c++filt. +* date: (coreutils)date invocation. Print/set system date and time. +* dd: (coreutils)dd invocation. Copy and convert a file. +* df: (coreutils)df invocation. Report file system disk usage. +* diff3: (diff)Invoking diff3. Compare 3 files line by line. +* diff: (diff)Invoking diff. Compare 2 files line by line. +* dir: (coreutils)dir invocation. List directories briefly. +* dircolors: (coreutils)dircolors invocation. Color setup for ls. +* dirname: (coreutils)dirname invocation. Strip non-directory suffix. +* dlltool: (binutils)dlltool. Create files needed to build and use DLLs. +* dmp: (web2c)Dmp invocation. Troff->MPX (MetaPost pictures). +* du: (coreutils)du invocation. Report on disk usage. +* dvicopy: (web2c)DVIcopy invocation. Virtual font expansion +* dvipng: (dvipng)Invoking dvipng. A DVI-to-PNG translator. +* dvitomp: (web2c)DVItoMP invocation. DVI to MPX (MetaPost pictures). +* dvitype: (web2c)DVItype invocation. DVI to human-readable text. +* echo: (coreutils)echo invocation. Print a line of text. +* edit-pr: (gnats)Invoking edit-pr. Changing bugs. +* egrep: (grep)Invoking. grep -E. +* env: (coreutils)env invocation. Modify the environment. +* expand: (coreutils)expand invocation. Convert tabs to spaces. +* expr: (coreutils)expr invocation. Evaluate expressions. +* factor: (coreutils)factor invocation. Print prime factors +* false: (coreutils)false invocation. Do nothing, unsuccessfully. +* fgrep: (fgrep)Invoking. grep -F. +* fid: (id-utils)fid invocation. Listing a file's tokens. +* file-pr: (gnats)file-pr. Processing incoming traffic. +* find: (find)Invoking find. Finding and acting on files. +* fmt: (coreutils)fmt invocation. Reformat paragraph text. +* fnid: (id-utils)fnid invocation. Looking up file names. +* fold: (coreutils)fold invocation. Wrap long input lines. +* frm: (mailutils)frm. List headers from a mailbox. +* ftp: (inetutils)ftp invocation. File Transfer Protocol. +* ftpd: (inetutils)ftpd invocation. FTP Daemon. +* gcal2txt: (gcal)Invoking gcal2txt. Calendar resource to text file. +* gftodvi: (web2c)GFtoDVI invocation. Generic font proofsheets. +* gftopk: (web2c)GFtoPK invocation. Generic to packed fonts. +* gftype: (web2c)GFtype invocation. GF to human-readable text. +* git: (git). GNU interactive tools. +* groups: (coreutils)groups invocation. Print group names a user is in. +* guimb: (mailutils)guimb. Mailbox processing language. +* gunzip: (gzip)Overview. Decompression. +* gzexe: (gzip)Overview. Compress executables. +* head: (coreutils)head invocation. Output the first part of files. +* hostid: (coreutils)hostid invocation. Print numeric host identifier. +* hostname: (coreutils)hostname invocation. Print or set system name. +* id: (coreutils)id invocation. Print user identity. +* ifnames: (autoconf)ifnames Invocation. Listing conditionals in source. +* imap4d: (mailutils)imap4d. IMAP4 daemon. +* inetd: (inetutils)inetd invocation. Internet super-server. +* inimf: (web2c)inimf invocation. Initial Metafont. +* inimp: (web2c)inimp invocation. Initial MetaPost. +* initex: (web2c)initex invocation. Initial TeX. +* install: (coreutils)install invocation. Copy and change attributes. +* join: (coreutils)join invocation. Join lines on a common field. +* kill: (coreutils)kill invocation. Send a signal to processes. +* kpsewhich: (kpathsea)Invoking kpsewhich. TeX file searching. +* libtoolize: (libtool)Invoking libtoolize. Adding libtool support. +* lid: (id-utils)lid invocation. Matching words and patterns. +* link: (coreutils)link invocation. Make hard links between files. +* ln: (coreutils)ln invocation. Make links between files. +* locate: (find)Invoking locate. Finding files in a database. +* logger: (inetutils)logger invocation. Logger. +* logname: (coreutils)logname invocation. Print current login name. +* ls: (coreutils)ls invocation. List directory contents. +* mail-files: (sharutils)mail-files invocation. Send files to remote site. +* mail.local: (mailutils)mail.local. Deliver mail to local mailbox. +* mail: (mailutils)mail. Send and receive mail. +* mailshar: (sharutils)mailshar invocation. Make and send a shell archive. +* makempx: (web2c)MakeMPX invocation. MetaPost label typesetting. +* maketexmf: (kpathsea)MakeTeX scripts. MF source generation. +* maketexpk: (kpathsea)MakeTeX scripts. PK bitmap generation. +* maketextex: (kpathsea)MakeTeX scripts. TeX source generation. +* maketextfm: (kpathsea)MakeTeX scripts. TeX font metric generation. +* md5sum: (coreutils)md5sum invocation. Print or check MD5 digests. +* mdiff: (wdiff)mdiff invocation. Line cluster finder. +* messages: (mailutils)messages. Count messages in mailbox. +* mf: (web2c)mf invocation. Creating typeface families. +* mft: (web2c)MFT invocation. Prettyprinting Metafont source. +* mgetty: (mgetty). Faxes, voicemail and more. +* mkdir: (coreutils)mkdir invocation. Create directories. +* mkfifo: (coreutils)mkfifo invocation. Create FIFOs (named pipes). +* mkid: (id-utils)mkid invocation. Creating an ID database. +* mknod: (coreutils)mknod invocation. Create special files. +* mp: (web2c)mp invocation. Creating technical diagrams. +* mpto: (web2c)MPto invocation. MetaPost label extraction. +* mv: (coreutils)mv invocation. Rename files. +* networking(inet) utilities: (inetutils). GNU networking utilities. +* newer: (web2c)Newer invocation. Compare modification times. +* nice: (coreutils)nice invocation. Modify niceness. +* nl: (coreutils)nl invocation. Number lines and write files. +* nlmconv: (binutils)nlmconv. Converts object code into an NLM. +* nm: (binutils)nm. List symbols from object files. +* nohup: (coreutils)nohup invocation. Immunize to hangups. +* objcopy: (binutils)objcopy. Copy and translate object files. +* objdump: (binutils)objdump. Display information from object files. +* od: (coreutils)od invocation. Dump files in octal, etc. +* paste: (coreutils)paste invocation. Merge lines of files. +* patch: (diff)Invoking patch. Apply a patch to a file. +* patgen: (web2c)Patgen invocation. Creating hyphenation patterns. +* pathchk: (coreutils)pathchk invocation. Check file name portability. +* ping: (inetutils)ping invocation. Packets to network hosts. +* pktogf: (web2c)PKtoGF invocation. Packed to generic fonts. +* pktype: (web2c)PKtype invocation. PK to human-readable text. +* pltotf: (web2c)PLtoTF invocation. Property list to TFM. +* pooltype: (web2c)Pooltype invocation. Display WEB pool files. +* pop3d: (mailutils)pop3d. POP3 daemon. +* pr-addr: (gnats)pr-addr. Bug report address retrieval. +* pr-edit: (gnats)pr-edit. The edit-pr driver. +* pr: (coreutils)pr invocation. Paginate or columnate files. +* printenv: (coreutils)printenv invocation. Print environment variables. +* printf: (coreutils)printf invocation. Format and print data. +* ptx: (coreutils)ptx invocation. Produce permuted indexes. +* pwd: (coreutils)pwd invocation. Print working directory. +* query-pr: (gnats)Invoking query-pr. Bug searching/reporting. +* queue-pr: (gnats)queue-pr. Handling incoming traffic. +* ranlib: (binutils)ranlib. Generate index to archive contents. +* rcp: (inetutils)rcp invocation. Strip non-directory suffix. +* readelf: (binutils)readelf. Display the contents of ELF format files. +* readlink: (coreutils)readlink invocation. Print referent of a symlink. +* readmsg: (mailutils)readmsg. Extract messages from a folder. +* rexecd: (inetutils)rexecd invocation. Remote execution server. +* rlogin: (inetutils)rlogin invocation. Remote login. +* rlogind: (inetutils)rlogind invocation. Remote login server. +* rm: (coreutils)rm invocation. Remove files. +* rmdir: (coreutils)rmdir invocation. Remove empty directories. +* rsh: (inetutils)rsh invocation. Remote shell. +* rshd: (inetutils)rshd invocation. Remote shell server. +* sdiff: (diff)Invoking sdiff. Merge 2 files side-by-side. +* send-pr: (gnats)Invoking send-pr. Submitting bugs. +* seq: (coreutils)seq invocation. Print numeric sequences +* sha1sum: (coreutils)sha1sum invocation. Print or check SHA-1 digests. +* sha2: (coreutils)sha2 utilities. Print or check SHA-2 digests. +* shar: (sharutils)shar invocation. Make a shell archive. +* shred: (coreutils)shred invocation. Remove files more securely. +* shuf: (coreutils)shuf invocation. Shuffling text files. +* sieve: (mailutils)sieve. Mail filtering utility. +* size: (binutils)size. List section sizes and total size. +* sleep: (coreutils)sleep invocation. Delay for a specified time. +* sort: (coreutils)sort invocation. Sort text files. +* split: (coreutils)split invocation. Split into fixed-size pieces. +* stat: (coreutils)stat invocation. Report file(system) status. +* strings: (binutils)strings. List printable strings from files. +* strip: (binutils)strip. Discard symbols. +* stty: (coreutils)stty invocation. Print/change terminal settings. +* su: (coreutils)su invocation. Modify user and group ID. +* sum: (coreutils)sum invocation. Print traditional checksum. +* sync: (coreutils)sync invocation. Synchronize memory and disk. +* syslogd: (inetutils)syslogd invocation. Syslog server. +* tabs: (tput)Invoking tabs. Tab settings. +* tac: (coreutils)tac invocation. Reverse files. +* tail: (coreutils)tail invocation. Output the last part of files. +* talk: (inetutils)talk invocation. Talk client. +* talkd: (inetutils)talkd invocation. Talk server. +* tangle: (web2c)Tangle invocation. WEB to Pascal. +* tar: (tar)tar invocation. Invoking GNU `tar'. +* tcal: (gcal)Invoking tcal. Run Gcal with tomorrow's date. +* tee: (coreutils)tee invocation. Redirect to multiple files. +* test: (coreutils)test invocation. File/string tests. +* testsuite: (autoconf)testsuite Invocation. Running an Autotest test suite. +* tex: (web2c)tex invocation. Typesetting. +* tftopl: (web2c)TFtoPL invocation. TFM -> property list. +* tftp: (inetutils)tftp invocation. Trivial FTP. +* touch: (coreutils)touch invocation. Change file timestamps. +* tput: (tput)Invoking tput. Termcap in shell scripts. +* tr: (coreutils)tr invocation. Translate characters. +* true: (coreutils)true invocation. Do nothing, successfully. +* tsort: (coreutils)tsort invocation. Topological sort. +* tty: (coreutils)tty invocation. Print terminal name. +* txt2gcal: (gcal)Invoking txt2gcal. Calendar text to resource file. +* umb-scheme: (umb-scheme). UMB Scheme Interpreter. +* uname: (coreutils)uname invocation. Print system information. +* unexpand: (coreutils)unexpand invocation. Convert spaces to tabs. +* unify: (wdiff)unify invocation. Diff format converter. +* uniq: (coreutils)uniq invocation. Uniquify files. +* unlink: (coreutils)unlink invocation. Removal via unlink(2). +* unshar: (sharutils)unshar invocation. Explode a shell archive. +* updatedb: (find)Invoking updatedb. Building the locate database. +* users: (coreutils)users invocation. Print current user names. +* uudecode: (sharutils)uudecode invocation. Restore file from 7-bits. +* uuencode: (sharutils)uuencode invocation. Force binary file to 7-bits. +* vdir: (coreutils)vdir invocation. List directories verbosely. +* vftovp: (web2c)VFtoVP invocation. Virtual font -> virtual pl. +* view-pr: (gnats)Invoking view-pr. Showing bug reports. +* virmf: (web2c)virmf invocation. Virgin Metafont. +* virmp: (web2c)virmp invocation. Virgin MetaPost. +* virtex: (web2c)virtex invocation. Virgin TeX. +* vptovf: (web2c)VPtoVF invocation. Virtual pl -> virtual font. +* wc: (coreutils)wc invocation. Line, word, and byte counts. +* weave: (web2c)Weave invocation. WEB to TeX. +* who: (coreutils)who invocation. Print who is logged in. +* whoami: (coreutils)whoami invocation. Print effective user ID. +* windmc: (binutils)windmc. Generator for Windows message resources. +* windres: (binutils)windres. Manipulate Windows resources. +* xargs: (find)Invoking xargs. Operating on many files. +* xtokid: (id-utils)xtokid invocation. Testing mkid scanners. +* yes: (coreutils)yes invocation. Print a string indefinitely. +* zcat: (gzip)Overview. Decompression to stdout. +* zdiff: (gzip)Overview. Compare compressed files. +* zforce: (gzip)Overview. Force .gz extension on files. +* zgrep: (gzip)Overview. Search compressed files. +* zmore: (gzip)Overview. Decompression output by pages. +* zsh: (zsh). An enhanced Bourne shell. diff --git a/util/dvipdf.test b/util/dvipdf.test new file mode 100755 index 0000000..f66375b --- /dev/null +++ b/util/dvipdf.test @@ -0,0 +1,66 @@ +#! /bin/sh +# Copyright (C) 2006, 2007 Free Software Foundation, Inc. +# +# This file is part of GNU Texinfo. +# +# GNU Texinfo 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. +# +# GNU Texinfo 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/>. + +required='tex' + +. ./defs || exit 1 + +set -e + +# one_run ARGS -- FILES +# --------------------- +# Run texi2dvi with ARGS, expect the FILES to be left. Remove them. +one_run () +{ + # Use pstricks. + cat >input.tex <<EOF +\documentclass[a4paper]{article} +\usepackage{pst-node} +\pagestyle{empty} +\begin{document} +\begin{psmatrix} + A & B & C & D & E & F +\end{psmatrix} +\psset{arrows=->} +\nccircle{1,1}{0.5} +\nccircle[angleA=30]{1,2}{0.4} +\nccircle[arrows=-,nodesep=0.05]{1,3}{0.2} +\ncloop[angleB=180]{1,4}{1,4} +\ncloop[angleB=180,linearc=0.35,nodesep=0.1]{1,5}{1,5} +\ncloop[angleB=180,linearc=0.15,loopsize=0.4]{1,6}{1,6} + +\vspace{1cm} +\begin{psmatrix} + A & B & C & D +\end{psmatrix} +\psset{arrows=->,nodesep=0.05} +\ncangles[armA=0.8,armB=0,angleA=70,angleB=110,linearc=0.22]{1,1}{1,1} +\ncdiag[arm=0.9,angleA=70,angleB=110,linearc=0.3]{1,2}{1,2} +\ncdiag[arm=0.8,angleA=50,angleB=130,linearc=0.25]{1,3}{1,3} +\ncdiag[arm=0.8,angleA=50,angleB=130,linearc=0.28]{1,4}{1,4} +\end{document} +EOF + + TEXI2DVI_pass $(optionset_get 1 "$@") input.tex + # There should only be the expected and input files. + assert_and_remove_files $(optionset_get 2 "$@") input.tex +} + +one_run --dvipdf --batch --clean \ + -- \ + input.pdf diff --git a/util/fix-info-dir b/util/fix-info-dir new file mode 100755 index 0000000..b1144ed --- /dev/null +++ b/util/fix-info-dir @@ -0,0 +1,317 @@ +#!/bin/sh +#fix-info-dir (GNU texinfo) +VERSION=1.1 +#Copyright (C) 1998, 2003 Free Software Foundation, Inc. +#fix-info-dir comes with NO WARRANTY, to the extent permitted by law. +#You may redistribute copies of fix-info-dir +#under the terms of the GNU General Public License. +#For more information about these matters, see the files named COPYING." +#fix-info-dir was derived from update-info and gen-dir-node +# The skeleton file contains info topic names in the +# order they should appear in the output. There are three special +# lines that alter the behavior: a line consisting of just "--" causes +# the next line to be echoed verbatim to the output. A line +# containing just "%%" causes all the remaining filenames (wildcards +# allowed) in the rest of the file to be ignored. A line containing +# just "!!" exits the script when reached (unless preceded by a line +# containing just "--"). +#Author: Richard L. Hawes, rhawes@dmapub.dma.org. + +# ###SECTION 1### Constants +set -h 2>/dev/null +# ENVIRONMENT +if test -z "$TMPDIR"; then + TMPDIR="/usr/tmp" +fi +if test -z "$LINENO"; then + LINENO="0" +fi + +MENU_BEGIN='^\*\([ ]\)\{1,\}Menu:' +MENU_ITEM='^\* ([^ ]).*:([ ])+\(' +MENU_FILTER1='s/^\*\([ ]\)\{1,\}/* /' +MENU_FILTER2='s/\([ ]\)\{1,\}$//g' + +TMP_FILE1="${TMPDIR}/fx${$}.info" +TMP_FILE2="${TMPDIR}/fy${$}.info" +TMP_FILE_LIST="$TMP_FILE1 $TMP_FILE2" + +TRY_HELP_MSG="Try --help for more information" + +# ###SECTION 100### main program +#variables set by options +CREATE_NODE="" +DEBUG=":" +MODE="" +# +Total="0" +Changed="" + +while test "$*"; do + case "$1" in + -c|--create) CREATE_NODE="y";; + --debug) set -eux; DEBUG="set>&2";; + -d|--delete) MODE="Detect_Invalid";; + +d);; + --version) +cat<<VersionEOF +fix-info-dir (GNU Texinfo) $VERSION +Copyright (C) 1998 Free Software Foundation, Inc. +fix-info-dir comes with NO WARRANTY, to the extent permitted by law. +You may redistribute copies of fix-info-dir +under the terms of the GNU General Public License. +For more information about these matters, see the files named COPYING. +Author: Richard L. Hawes +VersionEOF + exit;; + + --help) +cat<<HelpEndOfFile +Usage: fix-info-dir [OPTION]... [INFO_DIR/[DIR_FILE]] [SKELETON] + +It detects and inserts missing menu items into the info dir file. +The info dir must be the current directory. + +Options: +-c, --create create a new info node +-d, --delete delete invalid menu items (ignore missing menu items) + --debug print debug information to standard error path + --help print this help message and exit + --version print current version and exit +Backup of the info node has a '.old' suffix added. This is a shell script. +Environment Variables: TMPDIR +Email bug reports to bug-texinfo@gnu.org. +HelpEndOfFile + exit;; + + [-+]*) echo "$0:$LINENO: \"$1\" is not a valid option">&2 + echo "$TRY_HELP_MSG">&2 + exit 2;; + *) break;; + esac + shift +done + +ORIGINAL_DIR=`pwd` + +if test "$#" -gt "0"; then + INFO_DIR="$1" + shift +else + INFO_DIR=$DEFAULT_INFO_DIR +fi + +if test ! -d "${INFO_DIR}"; then + DIR_FILE=`basename ${INFO_DIR}`; + INFO_DIR=`dirname ${INFO_DIR}`; +else + DIR_FILE="dir" +fi + +cd "$INFO_DIR"||exit + + +if test "$CREATE_NODE"; then + if test "$#" -gt "0"; then + if test `expr $1 : /` = '1'; then + SKELETON="$1" + else + SKELETON="$ORIGINAL_DIR/$1" + fi + if test ! -r "$SKELETON" && test -f "$SKELETON"; then + echo "$0:$LINENO: $SKELETON is not readable">&2 + exit 2 + fi + shift + else + SKELETON=/dev/null + + fi +else + if test ! -f "$DIR_FILE"; then + echo "$0:$LINENO: $DIR_FILE is irregular or nonexistant">&2 + exit 2 + elif test ! -r "$DIR_FILE"; then + echo "$0:$LINENO: $DIR_FILE is not readable">&2 + exit 2 + elif test ! -w "$DIR_FILE"; then + echo "$0:$LINENO: $DIR_FILE is not writeable">&2 + exit 2 + fi +fi + +if test "$#" -gt "0"; then + echo "$0:$LINENO: Too many parameters">&2 + echo "$TRY_HELP_MSG">&2 + exit 2 +fi + +if test -f "$DIR_FILE"; then + cp "$DIR_FILE" "$DIR_FILE.old" + echo "Backed up $DIR_FILE to $DIR_FILE.old." +fi + +if test "$CREATE_NODE"; then + if test "$MODE"; then + echo "$0:$LINENO: ERROR: Illogical option combination: -d -c">&2 + echo "$TRY_HELP_MSG">&2 + exit 2 + fi + echo "Creating new Info Node: `pwd`/$DIR_FILE" + Changed="y" + +{ + + ### output the dir header + echo "-*- Text -*-" + echo "This file was generated automatically by $0." + echo "This version was generated on `date`" + echo "by `whoami`@`hostname` for `pwd`" + + cat<<DIR_FILE_END_OF_FILE +This is the file .../info/$DIR_FILE, which contains the topmost node of the +Info hierarchy. The first time you invoke Info you start off +looking at that node, which is ($DIR_FILE)Top. + + +File: $DIR_FILE Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "?" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs topic, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: The list of major topics begins on the next line. + +DIR_FILE_END_OF_FILE + +### go through the list of files in the skeleton. If an info file +### exists, grab the ENTRY information from it. If an entry exists +### use it, otherwise create a minimal $DIR_FILE entry. + + # Read one line from the file. This is so that we can echo lines with + # whitespace and quoted characters in them. + while read fileline; do + # flag fancy features + if test ! -z "$echoline"; then # echo line + echo "$fileline" + echoline="" + continue + elif test "${fileline}" = "--"; then + # echo the next line + echoline="1" + continue + elif test "${fileline}" = "%%"; then + # skip remaining files listed in skeleton file + skip="1" + continue + elif test "${fileline}" = "!!"; then + # quit now + break + fi + + # handle files if they exist + for file in $fileline""; do + fname= + if test -z "$file"; then + break + fi + # Find the file to operate upon. + if test -r "$file"; then + fname="$file" + elif test -r "${file}.info"; then + fname="${file}.info" + elif test -r "${file}.gz"; then + fname="${file}.gz" + elif test -r "${file}.info.gz"; then + fname="${file}.info.gz" + else + echo "$0:$LINENO: can't find info file for ${file}?">&2 + continue + fi + + # if we found something and aren't skipping, do the entry + if test "$skip"; then + continue + fi + + infoname=`echo $file|sed -e 's/.info$//'` + entry=`zcat -f $fname|\ + sed -e '1,/START-INFO-DIR-ENTRY/d'\ + -e '/END-INFO-DIR-ENTRY/,$d'` + if [ ! -z "${entry}" ]; then + echo "${entry}" + else + echo "* ${infoname}: (${infoname})." + fi + Total=`expr "$Total" + "1"` + done + done +}>$DIR_FILE<$SKELETON +fi + +trap ' eval "$DEBUG"; rm -f $TMP_FILE_LIST; exit ' 0 +trap ' rm -f $TMP_FILE_LIST + exit ' 1 +trap ' rm -f $TMP_FILE_LIST + echo "$0:$LINENO: received INT signal.">&2 + exit ' 2 +trap ' rm -f $TMP_FILE_LIST + echo "$0:$LINENO: received QUIT signal.">&2 + exit ' 3 + +sed -e "1,/$MENU_BEGIN/d" -e "$MENU_FILTER1" -e "$MENU_FILTER2"<$DIR_FILE\ +|sed -n -e '/\* /{ +s/).*$//g +s/\.gz$// +s/\.info$// +s/^.*(//p +}'|sort -u>$TMP_FILE1 +ls -F|sed -e '/\/$/d' -e '/[-.][0-9]/d'\ + -e "/^$DIR_FILE\$/d" -e "/^$DIR_FILE.old\$/d"\ + -e 's/[*@]$//' -e 's/\.gz$//' -e 's/\.info$//'|sort>$TMP_FILE2 + +if test -z "$MODE"; then + #Detect Missing + DONE_MSG="total menu item(s) were inserted into `pwd`/$DIR_FILE" + for Info_Name in `comm -13 $TMP_FILE1 $TMP_FILE2`; do + if test -r "$Info_Name"; then + Info_File="$Info_Name" + elif test -r "${Info_Name}.info"; then + Info_File="${Info_Name}.info" + elif test -r "${Info_Name}.gz"; then + Info_File="${Info_Name}.gz" + elif test -r "${Info_Name}.info.gz"; then + Info_File="${Info_Name}.info.gz" + else + echo "$0:$LINENO: can't find info file for ${Info_Name}?">&2 + continue + fi + Changed="y" + if install-info $Info_File $DIR_FILE; then + Total=`expr "$Total" + "1"` + fi + done +else + # Detect Invalid + DONE_MSG="total invalid menu item(s) were removed from `pwd`/$DIR_FILE" + for Info_Name in `comm -23 $TMP_FILE1 $TMP_FILE2`; do + Changed="y" + if install-info --remove $Info_Name $DIR_FILE; then + Total=`expr "$Total" + "1"` + fi + done +fi + +# print summary +if test "$Changed"; then + echo "$Total $DONE_MSG" +else + echo "Nothing to do" +fi +rm -f $TMP_FILE_LIST +eval "$DEBUG" +exit 0 diff --git a/util/fixfonts b/util/fixfonts new file mode 100755 index 0000000..ee2ea71 --- /dev/null +++ b/util/fixfonts @@ -0,0 +1,84 @@ +#!/bin/sh +# Make links named `lcircle10' for all TFM and GF/PK files, if no +# lcircle10 files already exist. + +# Don't override definition of prefix and/or libdir if they are +# already defined in the environment. +if test "z${prefix}" = "z" ; then + prefix=/usr/local +else + # prefix may contain references to other variables, thanks to make. + eval prefix=\""${prefix}"\" +fi + +if test "z${libdir}" = "z" ; then + libdir="${prefix}/lib/tex" +else + # libdir may contain references to other variables, thanks to make. + eval libdir=\""${libdir}"\" +fi + +texlibdir="${libdir}" +texfontdir="${texlibdir}/fonts" + +# Directories for the different font formats, in case they're not all +# stored in one place. +textfmdir="${textfmdir-${texfontdir}}" +texpkdir="${texpkdir-${texfontdir}}" +texgfdir="${texgfdir-${texfontdir}}" + +test "z${TMPDIR}" = "z" && TMPDIR="/tmp" + +tempfile="${TMPDIR}/circ$$" +tempfile2="${TMPDIR}/circ2$$" + +# EXIT SIGHUP SIGINT SIGQUIT SIGTERM +#trap 'rm -f "${tempfile}" "${tempfile2}"' 0 1 2 3 15 + +# Find all the fonts with names that include `circle'. +(cd "${texfontdir}"; find . -name '*circle*' -print > "${tempfile}") + +# If they have lcircle10.tfm, assume everything is there, and quit. +if grep 'lcircle10\.tfm' "${tempfile}" > /dev/null 2>&1 ; then + echo "Found lcircle10.tfm." + exit 0 +fi + +# No TFM file for lcircle. Make a link to circle10.tfm if it exists, +# and then make a link to the bitmap files. +grep 'circle10\.tfm' "${tempfile}" > "${tempfile2}" \ + || { + echo "I can't find any circle fonts in ${texfontdir}. +If it isn't installed somewhere else, you need to get the Metafont sources +from somewhere, e.g., labrea.stanford.edu:pub/tex/latex/circle10.mf, and +run Metafont on them." + exit 1 + } + +# We have circle10.tfm. (If we have it more than once, take the first +# one.) Make the link. +tempfile2_line1="`sed -ne '1p;q' \"${tempfile2}\"`" +ln "${tempfile2_line1}" "${textfmdir}/lcircle10.tfm" +echo "Linked to ${tempfile2_line1}." + +# Now make a link for the PK files, if any. +(cd "${texpkdir}" + for f in `grep 'circle10.*pk' "${tempfile}"` ; do + set - `echo "$f" \ + | sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'` + ln "$f" "${1}/l${2}" + echo "Linked to $f." + done +) + +# And finally for the GF files. +(cd "${texgfdir}" + for f in `grep 'circle10.*gf' "${tempfile}"` ; do + set - `echo "$f" \ + | sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'` + ln "$f" "${1}/l${2}" + echo "Linked to $f." + done +) + +# eof diff --git a/util/fixref.gawk b/util/fixref.gawk new file mode 100644 index 0000000..4a692f7 --- /dev/null +++ b/util/fixref.gawk @@ -0,0 +1,143 @@ +#! /usr/local/bin/gawk -f + +# fixref.awk --- fix xrefs in texinfo documents +# Copyright 1991, 1998 Arnold David Robbins + +# FIXREF is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# FIXREF is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Updated: Jul 21 1992 --- change unknown +# Updated: Jul 18 1997 --- bug fix + +# usage: gawk -f fixref.awk input-file > output-file +# or if you have #!: fixref.awk input-file > output-file + +# Limitations: +# 1. no more than one cross reference on a line +# 2. cross references may not cross a newline + +BEGIN \ +{ + # we make two passes over the file. To do that we artificially + # tweak the argument vector to do a variable assignment + + if (ARGC != 2) { + printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr" + exit 1 + } + ARGV[2] = "pass=2" + ARGV[3] = ARGV[1] + ARGC = 4 + + # examine paragraphs + RS = "" + + heading = "@(chapter|appendix|unnumbered|(appendix(sec|subsec|subsubsec))|section|subsection|subsubsection|unnumberedsec|heading|top)" + + pass = 1 + + # put space between paragraphs on output + ORS = "\n\n" +} + +pass == 1 && NF == 0 { next } + +# pass == 1 && /@node/ \ +# bug fix 7/18/96 +pass == 1 && /^@node/ \ +{ + lname = name = "" + n = split($0, lines, "\n") + for (i = 1; i <= n; i++) { + if (lines[i] ~ ("^" heading)) { + sub(heading, "", lines[i]) + sub(/^[ \t]*/, "", lines[i]) + lname = lines[i] +# printf "long name is '%s'\n", lines[i] + } else if (lines[i] ~ /@node/) { + sub(/@node[ \t]*/, "", lines[i]) + sub(/[ \t]*,.*$/, "", lines[i]) + name = lines[i] +# printf "node name is '%s'\n", lines[i] + } + } + if (name && lname) + names[name] = lname + else if (lname) + printf("node name for %s missing!\n", lname) > "/dev/stderr" + else + printf("long name for %s missing!\n", name) > "/dev/stderr" + + if (name ~ /:/) + printf("node `%s' contains a `:'\n", name) > "/dev/stderr" + + if (lname) { + if (lname ~ /:/) + printf("name `%s' contains a `:'\n", lname) > "/dev/stderr" + else if (lname ~ /,/) { + printf("name `%s' contains a `,'\n", lname) > "/dev/stderr" + gsub(/,/, " ", lname) + names[name] = lname # added 7/18/97 + } + } +} + +pass == 2 && /@(x|px)?ref{/ \ +{ + # split the paragraph into lines + # write them out one by one after fixing them + n = split($0, lines, "\n") + for (i = 1; i <= n; i++) + if (lines[i] ~ /@(x|px)?ref{/) { + res = updateref(lines[i]) + printf "%s\n", res + } else + printf "%s\n", lines[i] + + printf "\n" # avoid ORS + next +} + +function updateref(orig, refkind, line) +{ + line = orig # work on a copy + + # find the beginning of the reference + match(line, "@(x|px)?ref{") + refkind = substr(line, RSTART, RLENGTH) + + # pull out just the node name + sub(/.*ref{/, "", line) + sub(/}.*$/, "", line) + sub(/,.*/, "", line) + +# debugging +# printf("found ref to node '%s'\n", line) > "/dev/stderr" + + # If the node name and the section name are the same + # we don't want to bother doing this. + + if (! (line in names)) # sanity checking + printf("no long name for %s\n", line) > "/dev/stderr" + else if (names[line] != line && names[line] !~ /[:,]/) { + # build up new ref + newref = refkind line ", ," names[line] "}" + pat = refkind line "[^}]*}" + + sub(pat, newref, orig) + } + + return orig +} + +pass == 2 { print } diff --git a/util/gdoc b/util/gdoc new file mode 100644 index 0000000..3c52fb0 --- /dev/null +++ b/util/gdoc @@ -0,0 +1,914 @@ +#!/usr/bin/perl + +## Copyright (c) 2002, 2003 Simon Josefsson ## +## added -texinfo, -listfunc ## +## man page revamp ## +## various improvements ## +## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## +## hacked to allow -tex option --nmav ## +## ## +## This software falls under the GNU Public License. Please read ## +## the COPYING file for more information ## + +# +# This will read a 'c' file and scan for embedded comments in the +# style of gnome comments (+minor extensions - see below). +# +# This program is modified by Nikos Mavroyanopoulos, for the gnutls +# project. + +# Note: This only supports 'c'. + +# usage: +# gdoc [ -docbook | -html | -text | -man | -tex | -texinfo | -listfunc ] +# [ -sourceversion verno ] [ -includefuncprefix ] [ -bugsto address ] +# [ -seeinfo infonode ] [ -copyright notice ] [ -verbatimcopying ] +# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfil +e +# +# Set output format using one of -docbook, -html, -text, -man, -tex, +# -texinfo, or -listfunc. Default is man. +# +# -sourceversion +# Version number for source code, e.g. '1.0.4'. Used in 'man' headers. +# Defaults to using current date. +# +# -includefuncprefix +# For man pages, generate a #include <FILE.h> based on the function +# prefix. For example, a function gss_init_sec_context will generate +# an include statement of #include <gss.h>. +# +# -bugsto address +# For man pages, include a section about reporting bugs and mention +# the given e-mail address, e.g 'bug-libidn@gnu.org'. +# +# -seeinfo infonode +# For man pages, include a section that point to an info manual +# for more information. +# +# -copyright notice +# For man pages, include a copyright section with the given +# notice after a preamble. Use, e.g., '2002, 2003 Simon Josefsson'. +# +# -verbatimcopying +# For man pages, and when the -copyright parameter is used, +# add a licensing statement that say verbatim copying is permitted. +# +# -function funcname +# If set, then only generate documentation for the given function(s). A +ll +# other functions are ignored. +# +# c files - list of 'c' files to process +# +# All output goes to stdout, with errors to stderr. + +# +# format of comments. +# In the following table, (...)? signifies optional structure. +# (...)* signifies 0 or more structure elements +# /** +# * function_name(:)? (- short description)? +# (* @parameterx: (description of parameter x)?)* +# (* a blank line)? +# * (Description:)? (Description of function)? +# * (Section header: (section description)? )* +# (*)?*/ +# +# So .. the trivial example would be: +# +# /** +# * my_function +# **/ +# +# If the Description: header tag is ommitted, then there must be a blank line +# after the last parameter specification. +# e.g. +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * +# * Does my stuff explained. +# */ +# +# or, could also use: +# /** +# * my_function - does my stuff +# * @my_arg: its mine damnit +# * Description: Does my stuff explained. +# */ +# etc. +# +# All descriptions can be multiline, apart from the short function description +. +# +# All descriptive text is further processed, scanning for the following specia +l +# patterns, which are highlighted appropriately. +# +# 'funcname()' - function +# '$ENVVAR' - environmental variable +# '&struct_name' - name of a structure +# '@parameter' - name of a parameter +# '%CONST' - name of a constant. + +# +# Extensions for LaTeX: +# +# 1. the symbol '->' will be replaced with a rightarrow +# 2. x^y with ${x}^{y}$. +# 3. xxx\: with xxx: + +use POSIX qw(strftime); + +# match expressions used to find embedded type information +$type_constant = "\\\%(\\w+)"; +$type_func = "(\\w+\\(\\))"; +$type_param = "\\\@(\\w+)"; +$type_struct = "\\\&(\\w+)"; +$type_env = "(\\\$\\w+)"; + + +# Output conversion substitutions. +# One for each output format + +# these work fairly well +%highlights_html = ( $type_constant, "<i>\$1</i>", + $type_func, "<b>\$1</b>", + $type_struct, "<i>\$1</i>", + $type_param, "<tt><b>\$1</b></tt>" ); +$blankline_html = "<p>"; + +%highlights_texinfo = ( $type_constant, "\\\@var{\$1}", + $type_func, "\\\@code{\$1}", + $type_struct, "\\\@code{\$1}", + $type_param, "\\\@code{\$1}" ); +$blankline_texinfo = ""; + +%highlights_tex = ( $type_constant, "{\\\\it \$1}", + $type_func, "{\\\\bf \$1}", + $type_struct, "{\\\\it \$1}", + $type_param, "{\\\\bf \$1}" ); +$blankline_tex = "\\\\"; + +# sgml, docbook format +%highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</repla +ceable>", + $type_func, "<function>\$1</function>", + $type_struct, "<structname>\$1</structname>", + $type_env, "<envar>\$1</envar>", + $type_param, "<parameter>\$1</parameter>" ); +$blankline_sgml = "</para><para>\n"; + +# these are pretty rough +%highlights_man = ( $type_constant, "\\n.I \\\"\$1\\\"\\n", + $type_func, "\\n.B \\\"\$1\\\"\\n", + $type_struct, "\\n.I \\\"\$1\\\"\\n", + $type_param."([\.\, ]*)\n?", "\\n.I \\\"\$1\$2\\\"\\n" ); +$blankline_man = ""; + +# text-mode +%highlights_text = ( $type_constant, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_param, "\$1" ); +$blankline_text = ""; + + +sub usage { + print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex | -texinf +o -listfunc ]\n"; + print " [ -sourceversion verno ] [ -includefuncprefix ]\n"; + print " [ -bugsto address ] [ -seeinfo infonode ] [ -copyright not +ice]\n"; + print " [ -verbatimcopying ]\n"; + print " [ -function funcname [ -function funcname ...] ]\n"; + print " c source file(s) > outputfile\n"; + exit 1; +} + +# read arguments +if ($#ARGV==-1) { + usage(); +} + +$verbose = 0; +$output_mode = "man"; +%highlights = %highlights_man; +$blankline = $blankline_man; +$modulename = "API Documentation"; +$sourceversion = strftime "%Y-%m-%d", localtime; +$function_only = 0; +while ($ARGV[0] =~ m/^-(.*)/) { + $cmd = shift @ARGV; + if ($cmd eq "-html") { + $output_mode = "html"; + %highlights = %highlights_html; + $blankline = $blankline_html; + } elsif ($cmd eq "-man") { + $output_mode = "man"; + %highlights = %highlights_man; + $blankline = $blankline_man; + } elsif ($cmd eq "-tex") { + $output_mode = "tex"; + %highlights = %highlights_tex; + $blankline = $blankline_tex; + } elsif ($cmd eq "-texinfo") { + $output_mode = "texinfo"; + %highlights = %highlights_texinfo; + $blankline = $blankline_texinfo; + } elsif ($cmd eq "-text") { + $output_mode = "text"; + %highlights = %highlights_text; + $blankline = $blankline_text; + } elsif ($cmd eq "-docbook") { + $output_mode = "sgml"; + %highlights = %highlights_sgml; + $blankline = $blankline_sgml; + } elsif ($cmd eq "-listfunc") { + $output_mode = "listfunc"; + } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling + document + $modulename = shift @ARGV; + } elsif ($cmd eq "-sourceversion") { + $sourceversion = shift @ARGV; + } elsif ($cmd eq "-includefuncprefix") { + $includefuncprefix = 1; + } elsif ($cmd eq "-bugsto") { + $bugsto = shift @ARGV; + } elsif ($cmd eq "-copyright") { + $copyright = shift @ARGV; + } elsif ($cmd eq "-verbatimcopying") { + $verbatimcopying = 1; + } elsif ($cmd eq "-seeinfo") { + $seeinfo = shift @ARGV; + } elsif ($cmd eq "-function") { # to only output specific functions + $function_only = 1; + $function = shift @ARGV; + $function_table{$function} = 1; + } elsif ($cmd eq "-v") { + $verbose = 1; + } elsif (($cmd eq "-h") || ($cmd eq "--help")) { + usage(); + } +} + +## +# dumps section contents to arrays/hashes intended for that purpose. +# +sub dump_section { + my $name = shift @_; + my $contents = join "\n", @_; + + if ($name =~ m/$type_constant/) { + $name = $1; +# print STDERR "constant section '$1' = '$contents'\n"; + $constants{$name} = $contents; + } elsif ($name =~ m/$type_param/) { +# print STDERR "parameter def '$1' = '$contents'\n"; + $name = $1; + $parameters{$name} = $contents; + } else { +# print STDERR "other section '$name' = '$contents'\n"; + $sections{$name} = $contents; + push @sectionlist, $name; + } +} + +## +# output function +# +# parameters, a hash. +# function => "function name" +# parameterlist => @list of parameters +# parameters => %parameter descriptions +# sectionlist => @list of sections +# sections => %descriont descriptions +# + +sub repstr { + $pattern = shift; + $repl = shift; + $match1 = shift; + $match2 = shift; + $match3 = shift; + $match4 = shift; + + $output = $repl; + $output =~ s,\$1,$match1,g; + $output =~ s,\$2,$match2,g; + $output =~ s,\$3,$match3,g; + $output =~ s,\$4,$match4,g; + + eval "\$return = qq/$output/"; + +# print "pattern $pattern matched 1=$match1 2=$match2 3=$match3 4=$match4 r +eplace $repl yielded $output interpolated $return\n"; + + $return; +} + +sub output_highlight { + my $contents = join "\n", @_; + my $line; + + foreach $pattern (keys %highlights) { +# print "scanning pattern $pattern ($highlights{$pattern})\n"; + $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2 +, $3, $4):gse; + } + foreach $line (split "\n", $contents) { + if ($line eq ""){ + print $lineprefix, $blankline; + } else { + print $lineprefix, $line; + } + print "\n"; + } +} + +sub just_highlight { + my $contents = join "\n", @_; + my $line; + my $ret = ""; + + foreach $pattern (keys %highlights) { +# print "scanning pattern $pattern ($highlights{$pattern})\n"; + $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2 +, $3, $4):gse; + } + foreach $line (split "\n", $contents) { + if ($line eq ""){ + $ret = $ret . $lineprefix . $blankline; + } else { + $ret = $ret . $lineprefix . $line; + } + $ret = $ret . "\n"; + } + + return $ret; +} + +# output in texinfo +sub output_texinfo { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print "\@deftypefun {" . $args{'functiontype'} . "} "; + print "{".$args{'function'}."} "; + print "("; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print $args{'parametertypes'}{$parameter}." \@var{".$parameter."}"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ", "; + } + } + print ")\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + if ($args{'parameters'}{$parameter}) { + print "\@var{".$parameter."}: "; + output_highlight($args{'parameters'}{$parameter}); + print "\n"; + } + } + foreach $section (@{$args{'sectionlist'}}) { + print "\n\@strong{$section:} " if $section ne $section_default; + $args{'sections'}{$section} =~ s:([{}]):\@\1:gs; + output_highlight($args{'sections'}{$section}); + } + print "\@end deftypefun\n\n"; +} + +# output in html +sub output_html { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + print "\n\n<a name=\"". $args{'function'} . "\"> </a><h2>Function</h2> +\n"; + + print "<i>".$args{'functiontype'}."</i>\n"; + print "<b>".$args{'function'}."</b>\n"; + print "("; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter. +"</b>\n"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ", "; + } + } + print ")\n"; + + print "<h3>Arguments</h3>\n"; + print "<dl>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parame +ter."</b>\n"; + print "<dd>"; + output_highlight($args{'parameters'}{$parameter}); + } + print "</dl>\n"; + foreach $section (@{$args{'sectionlist'}}) { + print "<h3>$section</h3>\n"; + print "<ul>\n"; + output_highlight($args{'sections'}{$section}); + print "</ul>\n"; + } + print "<hr>\n"; +} + +# output in tex +sub output_tex { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $func = $args{'function'}; + my $param; + my $param2; + my $sec; + my $check; + my $type; + + $func =~ s/_/\\_/g; + + print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\ +n"; + + $type = $args{'functiontype'}; + $type =~ s/_/\\_/g; + + print "{\\it ".$type."}\n"; + print "{\\bf ".$func."}\n"; + print "("; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + $param = $args{'parametertypes'}{$parameter}; + $param2 = $parameter; + $param =~ s/_/\\_/g; + $param2 =~ s/_/\\_/g; + + print "{\\it ".$param."} {\\bf ".$param2."}"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ", "; + } + } + print ")\n"; + + print "\n{\\large{Arguments}}\n"; + + print "\\begin{itemize}\n"; + $check=0; + foreach $parameter (@{$args{'parameterlist'}}) { + $param1 = $args{'parametertypes'}{$parameter}; + $param1 =~ s/_/\\_/g; + $param2 = $parameter; + $param2 =~ s/_/\\_/g; + + $check = 1; + print "\\item {\\it ".$param1."} {\\bf ".$param2."}: \n"; +# print "\n"; + + $param3 = $args{'parameters'}{$parameter}; + $param3 =~ s/&([a-zA-Z\_]+)/{\\it \1}/g; + + $out = just_highlight($param3); + $out =~ s/_/\\_/g; + print $out; + } + if ($check==0) { + print "\\item void\n"; + } + print "\\end{itemize}\n"; + + foreach $section (@{$args{'sectionlist'}}) { + $sec = $section; + $sec =~ s/_/\\_/g; + $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g; + + print "\n{\\large{$sec}}\\\\\n"; + print "\\begin{rmfamily}\n"; + + $sec = $args{'sections'}{$section}; + $sec =~ s/\\:/:/g; + $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g; + $sec =~ s/->/\$\\rightarrow\$/g; + $sec =~ s/([0-9]+)\^([0-9]+)/\$\{\1\}\^\{\2\}\$/g; + + $out = just_highlight($sec); + $out =~ s/_/\\_/g; + + print $out; + print "\\end{rmfamily}\n"; + } + print "\n"; +} + + +# output in sgml DocBook +sub output_sgml { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + my $id; + + $id = $args{'module'}."-".$args{'function'}; + $id =~ s/[^A-Za-z0-9]/-/g; + + print "<refentry>\n"; + print "<refmeta>\n"; + print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></r +efentrytitle>\n"; + print "</refmeta>\n"; + print "<refnamediv>\n"; + print " <refname>".$args{'function'}."</refname>\n"; + print " <refpurpose>\n"; + print " ".$args{'purpose'}."\n"; + print " </refpurpose>\n"; + print "</refnamediv>\n"; + + print "<refsynopsisdiv>\n"; + print " <title>Synopsis</title>\n"; + print " <funcsynopsis>\n"; + print " <funcdef>".$args{'functiontype'}." "; + print "<function>".$args{'function'}." "; + print "</function></funcdef>\n"; + +# print "<refsect1>\n"; +# print " <title>Synopsis</title>\n"; +# print " <funcsynopsis>\n"; +# print " <funcdef>".$args{'functiontype'}." "; +# print "<function>".$args{'function'}." "; +# print "</function></funcdef>\n"; + + $count = 0; + if ($#{$args{'parameterlist'}} >= 0) { + foreach $parameter (@{$args{'parameterlist'}}) { + print " <paramdef>".$args{'parametertypes'}{$parameter}; + print " <parameter>$parameter</parameter></paramdef>\n"; + } + } else { + print " <void>\n"; + } + print " </funcsynopsis>\n"; + print "</refsynopsisdiv>\n"; +# print "</refsect1>\n"; + + # print parameters + print "<refsect1>\n <title>Arguments</title>\n"; +# print "<para>\nArguments\n"; + if ($#{$args{'parameterlist'}} >= 0) { + print " <variablelist>\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " <varlistentry>\n <term><parameter>$parameter</parameter +></term>\n"; + print " <listitem>\n <para>\n"; + $lineprefix=" "; + output_highlight($args{'parameters'}{$parameter}); + print " </para>\n </listitem>\n </varlistentry>\n"; + } + print " </variablelist>\n"; + } else { + print " <para>\n None\n </para>\n"; + } + print "</refsect1>\n"; + + # print out each section + $lineprefix=" "; + foreach $section (@{$args{'sectionlist'}}) { + print "<refsect1>\n <title>$section</title>\n <para>\n"; +# print "<para>\n$section\n"; + if ($section =~ m/EXAMPLE/i) { + print "<example><para>\n"; + } + output_highlight($args{'sections'}{$section}); +# print "</para>"; + if ($section =~ m/EXAMPLE/i) { + print "</para></example>\n"; + } + print " </para>\n</refsect1>\n"; + } + + print "\n\n"; +} + +## +# output in man +sub output_man { + my %args = %{$_[0]}; + my ($parameter, $section); + my $count; + + print ".TH \"$args{'function'}\" 3 \"$args{'sourceversion'}\" \"". $args{' +module'} . "\" \"". $args{'module'} . "\"\n"; + + print ".SH NAME\n"; + + print $args{'function'}."\n"; + + print ".SH SYNOPSIS\n"; + print ".B #include <". lc((split /_/, $args{'function'})[0]) . ".h>\n" + if $args{'includefuncprefix'}; + print ".sp\n"; + print ".BI \"".$args{'functiontype'}." ".$args{'function'}."("; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print $args{'parametertypes'}{$parameter}." \" ".$parameter." \""; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ", "; + } + } + print ");\"\n"; + + print ".SH ARGUMENTS\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\" +12\n"; + output_highlight($args{'parameters'}{$parameter}); + } + foreach $section (@{$args{'sectionlist'}}) { + print ".SH \"" . uc($section) . "\"\n"; + output_highlight($args{'sections'}{$section}); + } + + if ($args{'bugsto'}) { + print ".SH \"REPORTING BUGS\"\n"; + print "Report bugs to <". $args{'bugsto'} . ">.\n"; + } + + if ($args{'copyright'}) { + print ".SH COPYRIGHT\n"; + print "Copyright \\(co ". $args{'copyright'} . ".\n"; + if ($args{'verbatimcopying'}) { + print ".br\n"; + print "Permission is granted to make and distribute verbatim copie +s of this\n"; + print "manual provided the copyright notice and this permission no +tice are\n"; + print "preserved on all copies.\n"; + } + } + + if ($args{'seeinfo'}) { + print ".SH \"SEE ALSO\"\n"; + print "The full documentation for\n"; + print ".B " . $args{'module'} . "\n"; + print "is maintained as a Texinfo manual. If the\n"; + print ".B info\n"; + print "and\n"; + print ".B " . $args{'module'} . "\n"; + print "programs are properly installed at your site, the command\n"; + print ".IP\n"; + print ".B info " . $args{'seeinfo'} . "\n"; + print ".PP\n"; + print "should give you access to the complete manual.\n"; + } +} + +sub output_listfunc { + my %args = %{$_[0]}; + print $args{'function'} . "\n"; +} + +## +# output in text +sub output_text { + my %args = %{$_[0]}; + my ($parameter, $section); + + print "Function = ".$args{'function'}."\n"; + print " return type: ".$args{'functiontype'}."\n\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n"; + print " -> ".$args{'parameters'}{$parameter}."\n"; + } + foreach $section (@{$args{'sectionlist'}}) { + print " $section:\n"; + print " -> "; + output_highlight($args{'sections'}{$section}); + } +} + +## +# generic output function - calls the right one based +# on current output mode. +sub output_function { +# output_html(@_); + eval "output_".$output_mode."(\@_);"; +} + + +## +# takes a function prototype and spits out all the details +# stored in the global arrays/hsahes. +sub dump_function { + my $prototype = shift @_; + + if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ || + $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/) + { + $return_type = $1; + $function_name = $2; + $args = $3; + +# print STDERR "ARGS = '$args'\n"; + + foreach $arg (split ',', $args) { + # strip leading/trailing spaces + $arg =~ s/^\s*//; + $arg =~ s/\s*$//; +# print STDERR "SCAN ARG: '$arg'\n"; + @args = split('\s', $arg); + +# print STDERR " -> @args\n"; + $param = pop @args; +# print STDERR " -> @args\n"; + if ($param =~ m/^(\*+)(.*)/) { + $param = $2; + push @args, $1; + } + if ($param =~ m/^(.*)(\[\])$/) { + $param = $1; + push @args, $2; + } +# print STDERR " :> @args\n"; + $type = join " ", @args; + + if ($parameters{$param} eq "" && $param != "void") { + $parameters{$param} = "-- undescribed --"; + print STDERR "Warning($lineno): Function parameter '$param' no +t described in '$function_name'\n"; + } + + push @parameterlist, $param; + $parametertypes{$param} = $type; + +# print STDERR "param = '$param', type = '$type'\n"; + } + } else { + print STDERR "Error($lineno): cannot understand prototype: '$prototype +'\n"; + return; + } + + if ($function_only==0 || defined($function_table{$function_name})) { + output_function({'function' => $function_name, + 'module' => $modulename, + 'sourceversion' => $sourceversion, + 'includefuncprefix' => $includefuncprefix, + 'bugsto' => $bugsto, + 'copyright' => $copyright, + 'verbatimcopying' => $verbatimcopying, + 'seeinfo' => $seeinfo, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameters' => \%parameters, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $function_purpose + }); + } +} + +###################################################################### +# main +# states +# 0 - normal code +# 1 - looking for function name +# 2 - scanning field start. +# 3 - scanning prototype. +$state = 0; +$section = ""; + +$doc_special = "\@\%\$\&"; + +$doc_start = "^/\\*\\*\$"; +$doc_end = "\\*/"; +$doc_com = "\\s*\\*\\s*"; +$doc_func = $doc_com."(\\w+):?"; +$doc_sect = $doc_com."([".$doc_special."[:upper:]][\\w ]+):(.*)"; +$doc_content = $doc_com."(.*)"; + +%constants = (); +%parameters = (); +@parameterlist = (); +%sections = (); +@sectionlist = (); + +$contents = ""; +$section_default = "Description"; # default section +$section = $section_default; + +$lineno = 0; +foreach $file (@ARGV) { + if (!open(IN,"<$file")) { + print STDERR "Error: Cannot open file $file\n"; + next; + } + while (<IN>) { + $lineno++; + + if ($state == 0) { + if (/$doc_start/o) { + $state = 1; # next line is always the function nam +e + } + } elsif ($state == 1) { # this line is the function name (always) + if (/$doc_func/o) { + $function = $1; + $state = 2; + if (/-(.*)/) { + $function_purpose = $1; + } else { + $function_purpose = ""; + } + if ($verbose) { + print STDERR "Info($lineno): Scanning doc for $function\n" +; + } + } else { + print STDERR "WARN($lineno): Cannot understand $_ on line $lin +eno", + " - I thought it was a doc line\n"; + $state = 0; + } + } elsif ($state == 2) { # look for head: lines, and include content + if (/$doc_sect/o) { + $newsection = $1; + $newcontents = $2; + + if ($contents ne "") { + dump_section($section, $contents); + $section = $section_default; + } + + $contents = $newcontents; + if ($contents ne "") { + $contents .= "\n"; + } + $section = $newsection; + } elsif (/$doc_end/) { + + if ($contents ne "") { + dump_section($section, $contents); + $section = $section_default; + $contents = ""; + } + +# print STDERR "end of doc comment, looking for prototype\n"; + $prototype = ""; + $state = 3; + } elsif (/$doc_content/) { + # miguel-style comment kludge, look for blank lines after + # @parameter line to signify start of description + if ($1 eq "" && $section =~ m/^@/) { + dump_section($section, $contents); + $section = $section_default; + $contents = ""; + } else { + $contents .= $1."\n"; + } + } else { + # i dont know - bad line? ignore. + print STDERR "WARNING($lineno): bad line: $_"; + } + } elsif ($state == 3) { # scanning for function { (end of prototype) + if (m#\s*/\*\s+MACDOC\s*#io) { + # do nothing + } + elsif (/([^\{]*)/) { + $prototype .= $1; + } + if (/\{/) { + $prototype =~ s@/\*.*?\*/@@gos; # strip comments. + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. + $prototype =~ s@^ +@@gos; # strip leading spaces + dump_function($prototype); + + $function = ""; + %constants = (); + %parameters = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + + $state = 0; + } + } + } +} + + + diff --git a/util/gen-dir-node b/util/gen-dir-node new file mode 100755 index 0000000..262bdd7 --- /dev/null +++ b/util/gen-dir-node @@ -0,0 +1,212 @@ +#!/bin/sh +# $Id: gen-dir-node,v 1.3 2004/04/11 17:56:47 karl Exp $ +# Generate the top-level Info node, given a directory of Info files +# and (optionally) a skeleton file. The output will be suitable for a +# top-level dir file. The skeleton file contains info topic names in the +# order they should appear in the output. There are three special +# lines that alter the behavior: a line consisting of just "--" causes +# the next line to be echoed verbatim to the output. A line +# containing just "%%" causes all the remaining filenames (wildcards +# allowed) in the rest of the file to be ignored. A line containing +# just "!!" exits the script when reached (unless preceded by a line +# containing just "--"). Once the script reaches the end of the +# skeleton file, it goes through the remaining files in the directory +# in order, putting their entries at the end. The script will use the +# ENTRY information in each info file if it exists. Otherwise it will +# make a minimal entry. + +# sent by Jeffrey Osier <jeffrey@cygnus.com>, who thinks it came from +# zoo@winternet.com (david d `zoo' zuhn) + +# modified 7 April 1995 by Joe Harrington <jh@tecate.gsfc.nasa.gov> to +# take special flags + +INFODIR=$1 +if [ $# = 2 ] ; then + SKELETON=$2 +else + SKELETON=/dev/null +fi + +skip= + +if [ $# -gt 2 ] ; then + echo usage: $0 info-directory [ skeleton-file ] 1>&2 + exit 1 +elif [ -z "${INFODIR}" ] ; then + INFODIR="%%DEFAULT_INFO_DIR%%" +else + true +fi + +if [ ! -d ${INFODIR} ] ; then + echo "$0: first argument must specify a directory" + exit 1 +fi + +### output the dir header +echo "-*- Text -*-" +echo "This file was generated automatically by $0." +echo "This version was generated on `date`" +echo "by `whoami`@`hostname` for `(cd ${INFODIR}; pwd)`" + +cat << moobler +\$Id: gen-dir-node,v 1.3 2004/04/11 17:56:47 karl Exp $ +This is the file .../info/dir, which contains the topmost node of the +Info hierarchy. The first time you invoke Info you start off +looking at that node, which is (dir)Top. + +File: dir Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "?" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs topic, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: The list of major topics begins on the next line. + +moobler + +### go through the list of files in the skeleton. If an info file +### exists, grab the ENTRY information from it. If an entry exists +### use it, otherwise create a minimal dir entry. +### +### Then remove that file from the list of existing files. If any +### additional files remain (ones that don't have a skeleton entry), +### then generate entries for those in the same way, putting the info for +### those at the end.... + +infofiles=`(cd ${INFODIR}; /bin/ls | grep -v '\-[0-9]*$' | egrep -v '^dir$|^dir\.info$|^dir\.orig$')` + +# echoing gets clobbered by backquotes; we do it the hard way... +lines=`wc $SKELETON | awk '{print $1}'` +line=1 +while [ $lines -ge $line ] ; do + # Read one line from the file. This is so that we can echo lines with + # whitespace and quoted characters in them. + fileline=`awk NR==$line $SKELETON` + + # flag fancy features + if [ ! -z "$echoline" ] ; then # echo line + echo "$fileline" + fileline= + echoline= + elif [ "${fileline}" = "--" ] ; then # should we echo the next line? + echoline=1 + elif [ "${fileline}" = "%%" ] ; then # eliminate remaining files from dir? + skip=1 + elif [ "${fileline}" = "!!" ] ; then # quit now + exit 0 + fi + + # handle files if they exist + for file in $fileline"" ; do # expand wildcards ("" handles blank lines) + + fname= + + if [ -z "$echoline" ] && [ ! -z "$file" ] ; then + # Find the file to operate upon. Check both possible names. + infoname=`echo $file | sed 's/\.info$//'` + noext= + ext= + if [ -f ${INFODIR}/$infoname ] ; then + noext=$infoname + fi + if [ -f ${INFODIR}/${infoname}.info ] ; then + ext=${infoname}.info + fi + + # If it exists with both names take what was said in the file. + if [ ! -z "$ext" ] && [ ! -z "$noext" ]; then + fname=$file + warn="### Warning: $ext and $noext both exist! Using ${file}. ###" + elif [ ! -z "${noext}${ext}" ]; then + # just take the name if it exists only once + fname=${noext}${ext} + fi + + # if we found something and aren't skipping, do the entry + if [ ! -z "$fname" ] ; then + if [ -z "$skip" ] ; then + + if [ ! -z "$warn" ] ; then # issue any warning + echo $warn + warn= + fi + + entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \ + -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/$fname` + if [ ! -z "${entry}" ] ; then + echo "${entry}" + else + echo "* ${infoname}: (${infoname})." + fi + fi + + # remove the name from the directory listing + infofiles=`echo "" ${infofiles} "" | sed -e "s/ ${fname} / /" -e "s/ / /g"` + + fi + + fi + + done + + line=`expr $line + 1` +done + +if [ -z "${infofiles}" ] ; then + exit 0 +elif [ $lines -gt 0 ]; then + echo +fi + +# Sort remaining files by INFO-DIR-SECTION. +prevsect= +filesectdata=`(cd ${INFODIR}; fgrep INFO-DIR-SECTION /dev/null ${infofiles} | \ + fgrep -v 'INFO-DIR-SECTION Miscellaneous' | \ + sort -t: -k2 -k1 | tr ' ' '_')` +for sectdata in ${filesectdata}; do + file=`echo ${sectdata} | cut -d: -f1` + section=`sed -n -e 's/^INFO-DIR-SECTION //p' ${INFODIR}/${file}` + infofiles=`echo "" ${infofiles} "" | sed -e "s/ ${file} / /" -e "s/ / /g"` + + if [ "${prevsect}" != "${section}" ] ; then + if [ ! -z "${prevsect}" ] ; then + echo "" + fi + echo "${section}" + prevsect="${section}" + fi + + infoname=`echo $file | sed 's/\.info$//'` + entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \ + -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}` + if [ ! -z "${entry}" ] ; then + echo "${entry}" + elif [ ! -d "${INFODIR}/${file}" ] ; then + echo "* ${infoname}: (${infoname})." + fi +done + +# Process miscellaneous files. +for file in ${infofiles}; do + if [ ! -z "${prevsect}" ] ; then + echo "" + echo "Miscellaneous" + prevsect="" + fi + + infoname=`echo $file | sed 's/\.info$//'` + entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \ + -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}` + + if [ ! -z "${entry}" ] ; then + echo "${entry}" + elif [ ! -d "${INFODIR}/${file}" ] ; then + echo "* ${infoname}: (${infoname})." + fi +done diff --git a/util/gendocs.sh b/util/gendocs.sh new file mode 100755 index 0000000..aded2c4 --- /dev/null +++ b/util/gendocs.sh @@ -0,0 +1,351 @@ +#!/bin/sh +# gendocs.sh -- generate a GNU manual in many formats. This script is +# mentioned in maintain.texi. See the help message below for usage details. + +scriptversion=2008-03-05.14 + +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, +# or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Original author: Mohit Agarwal. +# Send bug reports and any other correspondence to bug-texinfo@gnu.org. + +prog=`basename "$0"` +srcdir=`pwd` + +scripturl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs.sh" +templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/~checkout~/texinfo/texinfo/util/gendocs_template" + +: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="} +: ${MAKEINFO="makeinfo"} +: ${TEXI2DVI="texi2dvi -t @finalout"} +: ${DVIPS="dvips"} +: ${DOCBOOK2HTML="docbook2html"} +: ${DOCBOOK2PDF="docbook2pdf"} +: ${DOCBOOK2PS="docbook2ps"} +: ${DOCBOOK2TXT="docbook2txt"} +: ${GENDOCS_TEMPLATE_DIR="."} +: ${TEXI2HTML="texi2html"} +unset CDPATH +unset use_texi2html + +version="gendocs.sh $scriptversion + +Copyright (C) 2007 Free Software Foundation, Inc. +There is NO warranty. You may redistribute this software +under the terms of the GNU General Public License. +For more information about these matters, see the files named COPYING." + +usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE + +Generate various output formats from PACKAGE.texinfo (or .texi or .txi) source. +See the GNU Maintainers document for a more extensive discussion: + http://www.gnu.org/prep/maintain_toc.html + +Options: + -o OUTDIR write files into OUTDIR, instead of manual/. + --docbook convert to DocBook too (xml, txt, html, pdf and ps). + --html ARG pass indicated ARG to makeinfo or texi2html for HTML targets. + --texi2html use texi2html to generate HTML targets. + --help display this help and exit successfully. + --version display version information and exit successfully. + +Simple example: $prog emacs \"GNU Emacs Manual\" + +Typical sequence: + cd YOURPACKAGESOURCE/doc + wget \"$scripturl\" + wget \"$templateurl\" + $prog YOURMANUAL \"GNU YOURMANUAL - One-line description\" + +Output will be in a new subdirectory \"manual\" (by default, use -o OUTDIR +to override). Move all the new files into your web CVS tree, as +explained in the Web Pages node of maintain.texi. + +MANUAL-TITLE is included as part of the HTML <title> of the overall +manual/index.html file. It should include the name of the package being +documented. manual/index.html is created by substitution from the file +$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the +generic template for your own purposes.) + +If you have several manuals, you'll need to run this script several +times with different YOURMANUAL values, specifying a different output +directory with -o each time. Then write (by hand) an overall index.html +with links to them all. + +If a manual's texinfo sources are spread across several directories, +first copy or symlink all Texinfo sources into a single directory. +(Part of the script's work is to make a tar.gz of the sources.) + +You can set the environment variables MAKEINFO, TEXI2DVI, and DVIPS to +control the programs that get executed, and GENDOCS_TEMPLATE_DIR to +control where the gendocs_template file is looked for. (With --docbook, +the environment variables DOCBOOK2HTML, DOCBOOK2PDF, DOCBOOK2PS, and +DOCBOOK2TXT are also respected.) + +By default, makeinfo is run in the default (English) locale, since +that's the language of most Texinfo manuals. If you happen to have a +non-English manual and non-English web site, check the SETLANG setting +in the source. + +Email bug reports or enhancement requests to bug-texinfo@gnu.org. +" + +calcsize() +{ + size=`ls -ksl $1 | awk '{print $1}'` + echo $size +} + +outdir=manual +html= +PACKAGE= +MANUAL_TITLE= + +while test $# -gt 0; do + case $1 in + --help) echo "$usage"; exit 0;; + --version) echo "$version"; exit 0;; + -o) shift; outdir=$1;; + --docbook) docbook=yes;; + --html) shift; html=$1;; + --texi2html) use_texi2html=1;; + -*) + echo "$0: Unknown or ambiguous option \`$1'." >&2 + echo "$0: Try \`--help' for more information." >&2 + exit 1;; + *) + if test -z "$PACKAGE"; then + PACKAGE=$1 + elif test -z "$MANUAL_TITLE"; then + MANUAL_TITLE=$1 + else + echo "$0: extra non-option argument \`$1'." >&2 + exit 1 + fi;; + esac + shift +done + +if test -s "$srcdir/$PACKAGE.texinfo"; then + srcfile=$srcdir/$PACKAGE.texinfo +elif test -s "$srcdir/$PACKAGE.texi"; then + srcfile=$srcdir/$PACKAGE.texi +elif test -s "$srcdir/$PACKAGE.txi"; then + srcfile=$srcdir/$PACKAGE.txi +else + echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2 + exit 1 +fi + +if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then + echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2 + echo "$0: it is available from $templateurl." >&2 + exit 1 +fi + +case $outdir in + /*) dotdot_outdir="$outdir";; + *) dotdot_outdir="../$outdir";; +esac + +echo Generating output formats for $srcfile + +cmd="$SETLANG $MAKEINFO -o $PACKAGE.info \"$srcfile\"" +echo "Generating info files... ($cmd)" +eval "$cmd" +mkdir -p $outdir/ +tar czf $outdir/$PACKAGE.info.tar.gz $PACKAGE.info* +info_tgz_size=`calcsize $outdir/$PACKAGE.info.tar.gz` +# do not mv the info files, there's no point in having them available +# separately on the web. + +cmd="${TEXI2DVI} \"$srcfile\"" +echo "Generating dvi ... ($cmd)" +eval "$cmd" + +# now, before we compress dvi: +echo Generating postscript... +${DVIPS} $PACKAGE -o +gzip -f -9 $PACKAGE.ps +ps_gz_size=`calcsize $PACKAGE.ps.gz` +mv $PACKAGE.ps.gz $outdir/ + +# compress/finish dvi: +gzip -f -9 $PACKAGE.dvi +dvi_gz_size=`calcsize $PACKAGE.dvi.gz` +mv $PACKAGE.dvi.gz $outdir/ + +cmd="${TEXI2DVI} --pdf \"$srcfile\"" +echo "Generating pdf ... ($cmd)" +eval "$cmd" +pdf_size=`calcsize $PACKAGE.pdf` +mv $PACKAGE.pdf $outdir/ + +cmd="$SETLANG $MAKEINFO -o $PACKAGE.txt --no-split --no-headers \"$srcfile\"" +echo "Generating ASCII... ($cmd)" +eval "$cmd" +ascii_size=`calcsize $PACKAGE.txt` +gzip -f -9 -c $PACKAGE.txt >$outdir/$PACKAGE.txt.gz +ascii_gz_size=`calcsize $outdir/$PACKAGE.txt.gz` +mv $PACKAGE.txt $outdir/ + +html_split() { + cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html --split=$1 $html --node-files \"$srcfile\"" + echo "Generating html by $1... ($cmd)" + eval "$cmd" + split_html_dir=$PACKAGE.html + ( + cd ${split_html_dir} || exit 1 + ln -sf ${PACKAGE}.html index.html + tar -czf $dotdot_outdir/${PACKAGE}.html_$1.tar.gz -- *.html + ) + eval html_$1_tgz_size=`calcsize $outdir/${PACKAGE}.html_$1.tar.gz` + rm -f $outdir/html_$1/*.html + mkdir -p $outdir/html_$1/ + mv ${split_html_dir}/*.html $outdir/html_$1/ + rmdir ${split_html_dir} +} + +if test -z "$use_texi2html"; then + cmd="$SETLANG $MAKEINFO --no-split --html -o $PACKAGE.html $html \"$srcfile\"" + echo "Generating monolithic html... ($cmd)" + rm -rf $PACKAGE.html # in case a directory is left over + eval "$cmd" + html_mono_size=`calcsize $PACKAGE.html` + gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz + html_mono_gz_size=`calcsize $outdir/$PACKAGE.html.gz` + mv $PACKAGE.html $outdir/ + + cmd="$SETLANG $MAKEINFO --html -o $PACKAGE.html $html \"$srcfile\"" + echo "Generating html by node... ($cmd)" + eval "$cmd" + split_html_dir=$PACKAGE.html + ( + cd ${split_html_dir} || exit 1 + tar -czf $dotdot_outdir/${PACKAGE}.html_node.tar.gz -- *.html + ) + html_node_tgz_size=`calcsize $outdir/${PACKAGE}.html_node.tar.gz` + rm -f $outdir/html_node/*.html + mkdir -p $outdir/html_node/ + mv ${split_html_dir}/*.html $outdir/html_node/ + rmdir ${split_html_dir} +else + cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $html \"$srcfile\"" + echo "Generating monolithic html... ($cmd)" + rm -rf $PACKAGE.html # in case a directory is left over + eval "$cmd" + html_mono_size=`calcsize $PACKAGE.html` + gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz + html_mono_gz_size=`calcsize $outdir/$PACKAGE.html.gz` + mv $PACKAGE.html $outdir/ + + html_split node + html_split chapter + html_split section +fi + +echo Making .tar.gz for sources... +srcfiles=`ls *.texinfo *.texi *.txi *.eps 2>/dev/null` +tar cvzfh $outdir/$PACKAGE.texi.tar.gz $srcfiles +texi_tgz_size=`calcsize $outdir/$PACKAGE.texi.tar.gz` + +if test -n "$docbook"; then + cmd="$SETLANG $MAKEINFO -o - --docbook \"$srcfile\" > ${srcdir}/$PACKAGE-db.xml" + echo "Generating docbook XML... $(cmd)" + eval "$cmd" + docbook_xml_size=`calcsize $PACKAGE-db.xml` + gzip -f -9 -c $PACKAGE-db.xml >$outdir/$PACKAGE-db.xml.gz + docbook_xml_gz_size=`calcsize $outdir/$PACKAGE-db.xml.gz` + mv $PACKAGE-db.xml $outdir/ + + cmd="${DOCBOOK2HTML} -o $split_html_db_dir ${outdir}/$PACKAGE-db.xml" + echo "Generating docbook HTML... ($cmd)" + eval "$cmd" + split_html_db_dir=html_node_db + ( + cd ${split_html_db_dir} || exit 1 + tar -czf $dotdot_outdir/${PACKAGE}.html_node_db.tar.gz -- *.html + ) + html_node_db_tgz_size=`calcsize $outdir/${PACKAGE}.html_node_db.tar.gz` + rm -f $outdir/html_node_db/*.html + mkdir -p $outdir/html_node_db + mv ${split_html_db_dir}/*.html $outdir/html_node_db/ + rmdir ${split_html_db_dir} + + cmd="${DOCBOOK2TXT} ${outdir}/$PACKAGE-db.xml" + echo "Generating docbook ASCII... ($cmd)" + eval "$cmd" + docbook_ascii_size=`calcsize $PACKAGE-db.txt` + mv $PACKAGE-db.txt $outdir/ + + cmd="${DOCBOOK2PS} ${outdir}/$PACKAGE-db.xml" + echo "Generating docbook PS... $(cmd)" + eval "$cmd" + gzip -f -9 -c $PACKAGE-db.ps >$outdir/$PACKAGE-db.ps.gz + docbook_ps_gz_size=`calcsize $outdir/$PACKAGE-db.ps.gz` + mv $PACKAGE-db.ps $outdir/ + + cmd="${DOCBOOK2PDF} ${outdir}/$PACKAGE-db.xml" + echo "Generating docbook PDF... ($cmd)" + eval "$cmd" + docbook_pdf_size=`calcsize $PACKAGE-db.pdf` + mv $PACKAGE-db.pdf $outdir/ +fi + +echo Writing index file... +if test -z "$use_texi2html"; then + CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\ + /%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d" +else + CONDS="/%%ENDIF.*%%/d;/%%IF *HTML_SECTION%%/d;/%%IF *HTML_CHAPTER%%/d" +fi +curdate=`$SETLANG date '+%B %d, %Y'` +sed \ + -e "s!%%TITLE%%!$MANUAL_TITLE!g" \ + -e "s!%%DATE%%!$curdate!g" \ + -e "s!%%PACKAGE%%!$PACKAGE!g" \ + -e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \ + -e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \ + -e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \ + -e "s!%%HTML_SECTION_TGZ_SIZE%%!$html_section_tgz_size!g" \ + -e "s!%%HTML_CHAPTER_TGZ_SIZE%%!$html_chapter_tgz_size!g" \ + -e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \ + -e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \ + -e "s!%%PDF_SIZE%%!$pdf_size!g" \ + -e "s!%%PS_GZ_SIZE%%!$ps_gz_size!g" \ + -e "s!%%ASCII_SIZE%%!$ascii_size!g" \ + -e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \ + -e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \ + -e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \ + -e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \ + -e "s!%%DOCBOOK_PS_GZ_SIZE%%!$docbook_ps_gz_size!g" \ + -e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \ + -e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \ + -e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \ + -e "s,%%SCRIPTURL%%,$scripturl,g" \ + -e "s!%%SCRIPTNAME%%!$prog!g" \ + -e "$CONDS" \ +$GENDOCS_TEMPLATE_DIR/gendocs_template >$outdir/index.html + +echo "Done! See $outdir/ subdirectory for new files." + +# Local variables: +# 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/util/gendocs_template b/util/gendocs_template new file mode 100644 index 0000000..abf3b1f --- /dev/null +++ b/util/gendocs_template @@ -0,0 +1,100 @@ +<!--#include virtual="/server/header.html" --> +<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title> +<!--#include virtual="/server/banner.html" --> +<h2>%%TITLE%%</h2> + +<!-- This document is in XML, and xhtml 1.0 --> +<!-- Please make sure to properly nest your tags --> +<!-- and ensure that your final document validates --> +<!-- consistent with W3C xhtml 1.0 and CSS standards --> +<!-- See validator.w3.org --> + +<address>Free Software Foundation</address> +<address>last updated %%DATE%%</address> + +<p>This manual (%%PACKAGE%%) is available in the following formats:</p> + +<ul> +<li><a href="%%PACKAGE%%.html">HTML + (%%HTML_MONO_SIZE%%K bytes)</a> - entirely on one web page.</li> +<li><a href="html_node/index.html">HTML</a> - with one web page per + node.</li> +%%IF HTML_SECTION%% +<li><a href="html_section/index.html">HTML</a> - with one web page per + section.</li> +%%ENDIF HTML_SECTION%% +%%IF HTML_CHAPTER%% +<li><a href="html_chapter/index.html">HTML</a> - with one web page per + chapter.</li> +%%ENDIF HTML_CHAPTER%% +<li><a href="%%PACKAGE%%.html.gz">HTML compressed + (%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on + one web page.</li> +<li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed + (%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> - + with one web page per node.</li> +%%IF HTML_SECTION%% +<li><a href="%%PACKAGE%%.html_section.tar.gz">HTML compressed + (%%HTML_SECTION_TGZ_SIZE%%K gzipped tar file)</a> - + with one web page per section.</li> +%%ENDIF HTML_SECTION%% +%%IF HTML_CHAPTER%% +<li><a href="%%PACKAGE%%.html_chapter.tar.gz">HTML compressed + (%%HTML_CHAPTER_TGZ_SIZE%%K gzipped tar file)</a> - + with one web page per chapter.</li> +%%ENDIF HTML_CHAPTER%% +<li><a href="%%PACKAGE%%.info.tar.gz">Info document + (%%INFO_TGZ_SIZE%%K bytes gzipped tar file)</a>.</li> +<li><a href="%%PACKAGE%%.txt">ASCII text + (%%ASCII_SIZE%%K bytes)</a>.</li> +<li><a href="%%PACKAGE%%.txt.gz">ASCII text compressed + (%%ASCII_GZ_SIZE%%K bytes gzipped)</a>.</li> +<li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file + (%%DVI_GZ_SIZE%%K bytes gzipped)</a>.</li> +<li><a href="%%PACKAGE%%.ps.gz">PostScript file + (%%PS_GZ_SIZE%%K bytes gzipped)</a>.</li> +<li><a href="%%PACKAGE%%.pdf">PDF file + (%%PDF_SIZE%%K bytes)</a>.</li> +<li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source + (%%TEXI_TGZ_SIZE%%K bytes gzipped tar file).</a></li> +</ul> + +<p>You can <a href="http://shop.fsf.org/">buy printed copies of +some manuals</a> (among other items) from the Free Software Foundation; +this helps support FSF activities.</p> + +<p>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%% +script</a>.)</p> + +<!-- If needed, change the copyright block at the bottom. In general, --> +<!-- all pages on the GNU web server should have the section about --> +<!-- verbatim copying. Please do NOT remove this without talking --> +<!-- with the webmasters first. --> +<!-- Please make sure the copyright date is consistent with the document --> +<!-- and that it is like this "2001, 2002" not this "2001-2002." --> +</div><!-- for id="content", starts in the include above --> +<!--#include virtual="/server/footer.html" --> +<div id="footer"> + +<p> +Please send FSF & GNU inquiries to +<a href="mailto:gnu@gnu.org"><em>gnu@gnu.org</em></a>. +There are also <a href="/contact/">other ways to contact</a> +the FSF. +<br /> +Please send broken links and other corrections or suggestions to +<a href="mailto:webmasters@gnu.org"><em>webmasters@gnu.org</em></a>. +</p> + +<p> +Copyright © 2008 Free Software Foundation, Inc., +</p> +<address>51 Franklin Street, Fifth Floor, Boston, MA 02111, USA</address> +<p>Verbatim copying and distribution of this entire article is +permitted in any medium, provided this notice is preserved. +</p> + +</div> +</div> +</body> +</html> diff --git a/util/infosrch b/util/infosrch new file mode 100755 index 0000000..af4a9a6 --- /dev/null +++ b/util/infosrch @@ -0,0 +1,104 @@ +#!/usr/local/bin/perl -w +# $Id: infosrch,v 1.2 2004/04/11 17:56:47 karl Exp $ +# infosrch does a regex search on an info manual. +# By Harry Putnam <reader@newsguy.com>. + +($myscript = $0) =~ s:^.*/::; +$six = ''; + +if($ARGV[0] eq "help"){ + &usage; + exit; +} +if($ARGV[0] eq "-e"){ + shift; + $six = "true"; +} +if(!$ARGV[1]){ + &usage; + exit; +} + +$target = shift; +$regex = shift; + +$shell_proc = "info --output - --subnodes 2>/dev/null $target"; + +open(SHELL_PROC," $shell_proc|"); +while(<SHELL_PROC>){ + chomp; + push @lines,$_; +} +close(SHELL_PROC); +$cnt = 0; +for(@lines){ + if(/$regex/ && !$six){ + print "$target\n $lines[($cnt-1)]\n<$cnt> $lines[$cnt]\n $lines[($cnt+1)]\n"; + print "-- \n"; + }elsif(/$regex/ && $six){ + print "$target\n"; + if($lines[($cnt-6)]){ + print " $lines[($cnt-6)]\n"; + } + if($lines[($cnt-5)]){ + print " $lines[($cnt-5)]\n"; + } + if($lines[($cnt-4)]){ + print " $lines[($cnt-4)]\n"; + } + if($lines[($cnt-3)]){ + print " $lines[($cnt-3)]\n"; + } + if($lines[($cnt-2)]){ + print " $lines[($cnt-2)]\n"; + } + if($lines[($cnt-1)]){ + print " $lines[($cnt-1)]\n"; + } + if($lines[$cnt]){ + print "$cnt $lines[$cnt]\n"; + } + if($lines[($cnt+1)]){ + print " $lines[($cnt+1)]\n"; + } + if($lines[($cnt+2)]){ + print " $lines[($cnt+2)]\n"; + } + if($lines[($cnt+3)]){ + print " $lines[($cnt+3)]\n"; + } + if($lines[($cnt+4)]){ + print " $lines[($cnt+4)]\n"; + } + if($lines[($cnt+5)]){ + print " $lines[($cnt+5)]\n"; + } + if($lines[($cnt+6)]){ + print " $lines[($cnt+6)]\n"; + } + print "-- \n"; + } + $cnt++; +} + +sub usage { + print <<EOM; + +Purpose: Extract full text from info node and search it by regex +Usage: $myscript [-e] TARGET REGEX + +Where TARGET is an info node such as `emacs', `bash' etc, and +REGEX is what you want to find in it. + +The -e flag is not required but if used then 6 lines preceding and six +lines following any hits will be printed. The default (with no -e flag) +is to print one line before and after. + +The output has the line number prepended to the line containing the +actual regex. + +Info command used: + info --output - --subnodes 2>/dev/null TARGET + +EOM +} diff --git a/util/install-info-html b/util/install-info-html new file mode 100644 index 0000000..4d10295 --- /dev/null +++ b/util/install-info-html @@ -0,0 +1,157 @@ +#!@BASH@ +# $Id: install-info-html,v 1.3 2004/04/11 17:56:47 karl Exp $ + +name=install-info-html +version=1.0 + +all= +index_dir=. + +# +# debugging +# +debug_echo=: + + +# +# print usage +# +function help () +{ + cat << EOF +$name $version +Install HTML info document. + +Usage: $name [OPTION]... [DOCUMENT-DIR]... + +Options: + -a,--all assume all subdirectories of index to be DOCUMENT-DIRs + -d,--dir=DIR set index directory to DIR (default=.) + -D,--debug print debugging info + -h,--help this help text + -v,--version show version +EOF +} + + +function cleanup () +{ + $debug_echo "cleaning ($?)..." +} + +trap cleanup 0 9 15 + +# +# Find command line options and switches +# + +# "x:" x takes argument +# +options="adhvW:" +# +# ugh, "\-" is a hack to support long options +# must be in double quotes for bash-2.0 + +while getopts "\-:$options" O +do + $debug_echo "O: \`$O'" + $debug_echo "arg: \`$OPTARG'" + case $O in + a) + all=yes + ;; + D) + [ "$debug_echo" = "echo" ] && set -x + debug_echo=echo + ;; + h) + help; + exit 0 + ;; + v) + echo $name $version + exit 0 + ;; + d) + index_dir=$OPTARG + ;; + # a long option! + -) + case "$OPTARG" in + a*|-a*) + all=yes + ;; + de*|-de*) + [ "$debug_echo" = "echo" ] && set -x + debug_echo=echo + ;; + h*|-h*) + help; + exit 0 + ;; + di*|-di*) + index_dir="`expr \"$OPTARG\" ':' '[^=]*=\(.*\)'`" + ;; + version|-version) + echo $name $version + exit 0 + ;; + *|-*) + echo "$0: invalid option -- \"$OPTARG\"" + help; + exit -1 + ;; + esac + esac +done +shift `expr $OPTIND - 1` + +# +# Input file name +# +if [ -z "$all" ] && [ -z "$1" ]; then + help + echo "$name: No HTML documents given" + exit 2 +fi + +if [ -n "$all" ] && [ -n "$1" ]; then + echo "$name: --all specified, ignoring DIRECTORY-DIRs" +fi + +if [ -n "$all" ]; then + document_dirs=`/bin/ls -d1 $index_dir` +else + document_dirs=$* +fi + +index_file=$index_dir/index.html +rm -f $index_file +echo -n "$name: Writing index: $index_file..." + +# head +cat >> $index_file <<EOF +<html> +<head><title>Info documentation index</title></head> +<body> +<h1>Info documentation index</h1> +This is the directory file \`index.html' a.k.a. \`DIR', which contains the +topmost node of the HTML Info hierarchy. +<p> +This is all very much Work in Progress (WiP). +<p> +<ul> +EOF + +#list +for i in $document_dirs; do + echo "<li> <a href=\"$i/$i.html\">$i</a></li>" +done >> $index_file + +# foot +cat >> $index_file <<EOF +</ul> +</body> +</html> +EOF +echo diff --git a/util/latex2html.test b/util/latex2html.test new file mode 100755 index 0000000..d52bf2f --- /dev/null +++ b/util/latex2html.test @@ -0,0 +1,79 @@ +#! /bin/sh +# Copyright (C) 2006, 2007 Free Software Foundation, Inc. +# +# This file is part of GNU Texinfo. +# +# GNU Texinfo 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. +# +# GNU Texinfo 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/>. + +required='hevea' + +. ./defs || exit 1 + +set -e + +# Force the creation of auxiliary files. +# Force it to be big enough to trigger the info file splitting. +{ + echo "\tableofcontents" + for section in 1 2 3 4 5 6 + do + echo "\section{$i}" + for subsection in 1 2 3 4 5 6 + do + echo "\subsection{$i}" + echo "$latex_paragraph" + done + done +} | +create_input_tex + + +# run_hevea_check FORMAT OPTIONS +# ------------------------------ +run_hevea_check () +{ + title "$@" + + format="$1" + shift + + # Testing the local build mode. + TEXI2DVI_pass --batch --$format "$@" input.tex + + # Compute the expected output. + outfiles=input.$out + case $format in + info) outfiles="$outfiles input.info-1 input.info-2";; + esac + + # Compute the aux files. + case $format:$@ in + *clean* ) auxfiles='';; + *tidy* ) auxfiles='input.t2d';; + html:*|text:* ) auxfiles='input.haux input.htoc';; + dvi:* ) auxfiles='input.aux input.log input.toc';; + * ) auxfiles='';; + esac + # There should only be the expected output and the source file. + assert_files input.tex $outfiles $auxfiles + rm -fr $outfiles $auxfiles +} + +for opt in "" "--clean" "--tidy" +do + for out in html info text + do + run_hevea_check $out $opt + done +done diff --git a/util/local.test b/util/local.test new file mode 100755 index 0000000..ff4aa79 --- /dev/null +++ b/util/local.test @@ -0,0 +1,59 @@ +#! /bin/sh +# Copyright (C) 2003, 2005, 2007, 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Texinfo. +# +# GNU Texinfo 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. +# +# GNU Texinfo 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/>. + +# Make sure no "local" variable identifier is used twice, since +# local is not actually portable. + +. ./defs || exit 1 + +set -e + +# Make sure quotes are used to protect the value. See the comment in +# texi2dvi itself about local. +if sed -e 's/^[ ]*#.*//' $TEXI2DVI | + $EGREP "\blocal [a-zA-Z_0-9]*=[^\"']" | + $EGREP -v "\blocal [a-zA-Z_0-9]*=[a-zA-Z0-9]*$" | + grep . +then + false +else + true +fi + + +# Make sure each name is used only once. +if sed -n -e 's/^#.*//' \ + -e 's/local \([a-zA-Z_0-9]*\)/\1/gp' $TEXI2DVI | + sort | + uniq -c | + grep -v '^.*1 ' | + grep . +then + false +else + true +fi + + +# Make sure we don't use $(). +if $FGREP '$(' $TEXI2DVI +then + false +else + true +fi diff --git a/util/outline.gawk b/util/outline.gawk new file mode 100644 index 0000000..fa67263 --- /dev/null +++ b/util/outline.gawk @@ -0,0 +1,144 @@ +#! /usr/local/bin/gawk -f + +# texi.outline --- produce an outline from a texinfo source file +# +# Copyright (C) 1998 Arnold David Robbins (arnold@gnu.org) +# +# TEXI.OUTLINE is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# TEXI.OUTLINE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# NOTE: +# This program uses gensub(), which is specific to gawk. +# With some work (split, substr, etc), it could be made to work +# on other awks, but it's not worth the trouble for me. + +BEGIN \ +{ + # Levels at which different nodes can be + Level["@top"] = 0 + Level["@appendix"] = 1 + Level["@chapter"] = 1 + Level["@majorheading"] = 1 + Level["@unnumbered"] = 1 + Level["@appendixsec"] = 2 + Level["@heading"] = 2 + Level["@section"] = 2 + Level["@unnumberedsec"] = 2 + Level["@unnumberedsubsec"] = 3 + Level["@appendixsubsec"] = 3 + Level["@subheading"] = 3 + Level["@subsection"] = 3 + Level["@appendixsubsubsec"] = 4 + Level["@subsubheading"] = 4 + Level["@subsubsection"] = 4 + Level["@unnumberedsubsubsec"] = 4 + + # insure that we were called correctly + if (ARGC != 2) { + printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr" + exit 1 + } + + # init header counters + app_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + app_h = 0 + l1_h = l2_h = l3_h = l4_h = 0 +} + +# skip lines we're not interested in +/^[^@]/ || ! ($1 in Level) { next } + +Level[$1] == 1 { + if ($1 !~ /^@unnumbered/ || $1 !~ /heading/) + l1_h++ + l2_h = l3_h = l4_h = 0 + Ntabs = 0 + Number = makenumber($1) + Title = maketitle($0) + print_title() +} + +Level[$1] == 2 { + l2_h++ + l3_h = l4_h = 0 + Ntabs = 1 + Number = makenumber($1) + Title = maketitle($0) + print_title() +} + +Level[$1] == 3 { + l3_h++ + l4_h = 0 + Ntabs = 2 + Number = makenumber($1) + Title = maketitle($0) + print_title() +} + +Level[$1] == 4 { + l4_h++ + Ntabs = 3 + Number = makenumber($1) + Title = maketitle($0) + print_title() +} + +# maketitle --- extract title + +function maketitle(str, text) +{ + $1 = "" # clobber section keyword + text = $0 + gsub(/^[ \t]*/, "", text) + text = gensub(/@[a-z]+{/, "", "g", text) + text = gensub(/([^@])}/, "\\1", "g", text) + return text +} + +# print_title --- print the title + +function print_title( i) +{ + for (i = 1; i <= Ntabs; i++) + printf "\t" + printf("%s %s\n", Number, Title) +} + +# makenumber --- construct a heading number from levels and section command + +function makenumber(command, result, lev1) +{ + result = "" + if (command ~ /^@appendix/) { + if (Level[command] == 1) + app_h++ + + lev1 = substr(app_letters, app_h, 1) + } else if (command ~ /^@unnumbered/ || command ~ /heading/) { + lev1 = "(unnumbered)" + } else + lev1 = l1_h "" + + result = lev1 "." + if (l2_h > 0) { + result = result l2_h "." + if (l3_h > 0) { + result = result l3_h "." + if (l4_h > 0) { + result = result l4_h "." + } + } + } + return result +} diff --git a/util/pdftexi2dvi b/util/pdftexi2dvi new file mode 100755 index 0000000..17708e7 --- /dev/null +++ b/util/pdftexi2dvi @@ -0,0 +1,19 @@ +#!/bin/sh +# $Id: pdftexi2dvi,v 1.3 2007/07/05 15:22:26 karl Exp $ +# Written by Thomas Esser. Public domain. +# Execute texi2dvi --pdf. + +test -f /bin/ksh && test -z "$RUNNING_KSH" \ + && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \ + && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; } +unset RUNNING_KSH + +test -f /bin/bsh && test -z "$RUNNING_BSH" \ + && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \ + && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; } +unset RUNNING_BSH + +# hack around a bug in zsh: +test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"' + +texi2dvi --pdf ${1+"$@"} diff --git a/util/prepinfo.awk b/util/prepinfo.awk new file mode 100644 index 0000000..18e668b --- /dev/null +++ b/util/prepinfo.awk @@ -0,0 +1,355 @@ +#! /usr/local/bin/gawk -f + +# prepinfo.awk --- fix node lines and menus +# +# Copyright 1998 Arnold Robbins, arnold@gnu.org +# +# PREPINFO is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# PREPINFO is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +BEGIN \ +{ + # manifest constants + TRUE = 1 + FALSE = 0 + + # Levels at which different nodes can be + Level["@top"] = 0 + Level["@appendix"] = 1 + Level["@chapter"] = 1 + Level["@majorheading"] = 1 + Level["@unnumbered"] = 1 + Level["@appendixsec"] = 2 + Level["@heading"] = 2 + Level["@section"] = 2 + Level["@unnumberedsec"] = 2 + Level["@unnumberedsubsec"] = 3 + Level["@appendixsubsec"] = 3 + Level["@subheading"] = 3 + Level["@subsection"] = 3 + Level["@appendixsubsubsec"] = 4 + Level["@subsubheading"] = 4 + Level["@subsubsection"] = 4 + Level["@unnumberedsubsubsec"] = 4 + + # Length of menus + Menumargin = 78 + + # Length of menu item + Min_menitem_length = 29 + + # insure that we were called correctly + if (ARGC != 2) { + printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr" + exit 1 + } + + # Arrange for two passes over input file + Pass = 1 + ARGV[2] = "Pass=2" + ARGV[3] = ARGV[1] + ARGC = 4 + Lastlevel = -1 + + # Initialize stacks + Up[-1] = "(dir)" + Prev[0] = "(dir)" + + if (Debug == "args") { + for (i = 0; i < ARGC; i++) + printf("ARGV[%d] = %s\n", i, ARGV[i]) > "/dev/stderr" + } +} + +$1 == "@node" \ +{ + Name = getnodename($0) + Nodeseen = TRUE + + if ((l = length(Name)) > Maxlen) + Maxlen = l + + if (Debug == "nodenames") + printf("Name = %s\n", Name) > "/dev/stderr" + + if (Pass == 1) + next +} + +Pass == 1 && /^@c(omment)?[ \t]+fakenode/ \ +{ + if (Debug == "fakenodes") + printf("fakenode at %d\n", FNR) > "/dev/stderr" + Fakenode = TRUE + next +} + +Pass == 1 && ($1 in Level) \ +{ + # skip fake nodes --- titles without associated @node lines + if (Fakenode) { + if (Debug == "fakenodes") + printf("%s at %d is a fakenode\n", $1, FNR) > "/dev/stderr" + Fakenode = FALSE + next + } + + if (Debug == "titles") + printf("Processing %s: Name = %s\n", $1, Name) > "/dev/stderr" + + # save type + type = $1 + + if (! Nodeseen) { + err_prefix() + printf("%s line with no @node or fakenode line\n", + type) > "/dev/stderr" + Badheading[FNR] = 1 + # ??? used ??? + next + } else + Nodeseen = FALSE # reset it + + # Squirrel away the info + levelnum = Level[type] + Node[Name ".level"] = levelnum + Node[Name ".name"] = Name + if (Debug == "titles") { + printf("Node[%s\".level\"] = %s\n", Name, Node[Name ".level"]) > "/dev/stderr" + printf("Node[%s\".name\"] = %s\n", Name, Node[Name ".name"]) > "/dev/stderr" + } + + if (levelnum == Lastlevel) { # e.g., two sections in a row + Node[Name ".up"] = Up[levelnum - 1] + if (levelnum in Prev) { + Node[Prev[levelnum] ".next"] = Name + Node[Name ".prev"] = Prev[levelnum] + } + Prev[levelnum] = Name + Up[levelnum] = Name # ??? + } else if (levelnum < Lastlevel) { # section, now chapter + Lastlevel = levelnum + Node[Name ".up"] = Up[levelnum - 1] + if (levelnum in Prev) { + Node[Name ".prev"] = Prev[levelnum] + Node[Prev[levelnum] ".next"] = Name + } + Prev[levelnum] = Name + Up[levelnum] = Name + } else { # chapter, now section, levelnum > Lastlevel + Node[Name ".up"] = Up[levelnum - 1] + Node[Up[Lastlevel] ".child"] = Name + Up[levelnum] = Name + Prev[levelnum] = Name + Lastlevel = levelnum + } + + # For master menu + if (Level[$1] >= 2) + List[++Sequence] = Name + + if (Debug == "titles") { + printf("Node[%s\".prev\"] = %s\n", Name, Node[Name ".prev"]) > "/dev/stderr" + printf("Node[%s\".up\"] = %s\n", Name, Node[Name ".up"]) > "/dev/stderr" + printf("Node[%s\".child\"] = %s\n", Name, Node[Name ".child"]) > "/dev/stderr" + } +} + +Pass == 2 && Debug == "dumptitles" && FNR <= 1 \ +{ + for (i in Node) + printf("Node[%s] = %s\n", i, Node[i]) | "sort 1>&2" + close("sort 1>&2") +} + +/^@menu/ && Pass == 1, /^@end[ \t]+menu/ && Pass == 1 \ +{ + if (/^@menu/ || /^@end[ \t]+menu/) + next + +# if (Debug == "menu") +# printf("processing: %s\n", $0) > "/dev/stderr" + + if (/^\*/) { + if (In_menitem) { # file away info from previousline + Node[node ".mendesc"] = desc + Node[node ".longdesc"] = longdesc + if (Debug == "mendesc") { + printf("Node[%s.mendesc] = %s\n", + node, Node[node ".mendesc"]) > "/dev/stderr" + printf("Node[%s.longdesc] = %s\n", + node, Node[node ".longdesc"]) > "/dev/stderr" + } + } + In_menitem = TRUE + + # pull apart menu item + $1 = "" # nuke ``*'' + $0 = $0 # reparse line + i1 = index($0, ":") + if (i1 <= 0) { + err_prefix() + printf("badly formed menu item") > "/dev/stderr" + next + } + if (substr($0, i1+1, 1) != ":") { # desc: node. long desc + i2 = index($0, ".") + if (i2 <= 0) { + err_prefix() + printf("badly formed menu item") > "/dev/stderr" + next + } + desc = substr($0, 1, i1 - 1) + sub(/^[ \t]+/, "", node) + sub(/[ \t]+$/, "", node) + longdesc = substr($0, i2 + 1) + } else { # nodname:: long desc + desc = "" + node = substr($0, 1, i1 - 1) + sub(/^[ \t]+/, "", node) + sub(/[ \t]+$/, "", node) + longdesc = substr($0, i1 + 2) + } + } else if (In_menitem) { # continuation line + longdesc = longdesc " " $0 + } else + In_menitem = FALSE + + Node[node ".mendesc"] = desc + Node[node ".longdesc"] = longdesc + if (Debug == "mendesc") { + printf("Node[%s.mendesc] = %s\n", + node, Node[node ".mendesc"]) > "/dev/stderr" + printf("Node[%s.longdesc] = %s\n", + node, Node[node ".longdesc"]) > "/dev/stderr" + } + + if (Debug == "menu") + printf("Menu:: Name %s: desc %s: longdesc %s\n", + node, desc, longdesc) > "/dev/stderr" +} + +function err_prefix() +{ + printf("%s: %s: %d: ", ARGV[0], FILENAME, FNR) > "/dev/stderr" +} + +function getnodename(str) +{ + sub(/@node[ \t]+/, "", str) + sub(/,.*/, "", str) + if (Debug == "nodenames") + printf("getnodename: return %s\n", str) > "/dev/stderr" + return str +} + +Pass == 2 && /^@node/ \ +{ + Name = getnodename($0) + + # Top node is special. It's next is the first child + n = Node[Name ".next"] + if (Node[Name ".level"] == 0 && n == "") + n = Node[Name ".child"] + + printf("@node %s, %s, %s, %s\n", Name, n, + Node[Name ".prev"] ? Node[Name ".prev"] : Node[Name ".up"], + Node[Name ".up"]) + next +} + +Pass == 2 && /^@menu/ \ +{ + # First, nuke current contents of menu + do { + if ((getline) <= 0) { + err_prefix() + printf("unexpected EOF inside menu\n") > "/dev/stderr" + exit 1 + } + } while (! /^@end[ \t]+menu/) + + # next, compute maximum length of a node name + max = 0 + for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) { + if ((n ".desc") in Node) + s = Node[n ".desc"] ": " n "." + else + s = n "::" + l = length(s) + if (l > max) + max = l + } + if (max < Min_menitem_length) + max = Min_menitem_length + + # now dump the menu + print "@menu" + + for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) { + print_menuitem(n, max) + } + print_menuitem(n, max) + + if (Name == "Top") { # Master Menu + if (Maxlen < Min_menitem_length) + Maxlen = Min_menitem_length + print "" + for (i = 1; i <= Sequence; i++) + print_menuitem(List[i], Maxlen) + print "" + } + print "@end menu" + next +} + +Pass == 2 # print + + +function print_menuitem(n, max, nodesc, i, dwords, count, p) +{ + nodesc = FALSE + if (! ((n ".longdesc") in Node)) { + err_prefix() + printf("warning: %s: no long description\n", n) > "/dev/stderr" + nodesc = TRUE + } else { + for (i in dwords) + delete dwords[i] + count = split(Node[n ".longdesc"], dwords, "[ \t\n]+") + } + if ((n ".desc") in Node) + s = Node[n ".desc"] ": " n "." + else + s = n "::" + printf("* %-*s", max, s) + + if (Debug == "mendescitem") + printf("<* %-*s>\n", max, s) > "/dev/stderr" + + p = max + 2 + if (! nodesc) { + for (i = 1; i <= count; i++) { + l = length(dwords[i]) + if (l == 0) + continue + if (p + l + 1 > Menumargin) { + printf("\n%*s", max + 2, " ") + p = max + 2 + } + printf(" %s", dwords[i]) + p += l + 1 + } + } + print "" +} diff --git a/util/tex3patch b/util/tex3patch new file mode 100755 index 0000000..046c794 --- /dev/null +++ b/util/tex3patch @@ -0,0 +1,70 @@ +#!/bin/sh +# Auxiliary script to work around TeX 3.0 bug. ---- tex3patch ---- +# patches texinfo.tex in current directory, or in directory given as arg. + +ANYVERSION=no + +for arg in $1 $2 +do + case $arg in + --dammit | -d ) ANYVERSION=yes ;; + + * ) dir=$arg + esac +done + +if [ -z "$dir" ]; then + dir='.' +fi + +if [ 2 -lt $# ] || [ ! -f "$dir/texinfo.tex" ]; then + echo "To patch texinfo.tex for peaceful coexistence with Unix TeX 3.0," + echo "run $0" + echo "with no arguments in the same directory as texinfo.tex; or run" + echo " $0 DIRECTORY" + echo "(where DIRECTORY is a path leading to texinfo.tex)." + exit +fi + +if [ -z "$TMPDIR" ]; then + TMPDIR=/tmp +fi + +echo "Checking for \`dummy.tfm'" + +( cd $TMPDIR; tex '\relax \batchmode \font\foo=dummy \bye' ) + +grep -s '3.0' $TMPDIR/texput.log +if [ 1 = "$?" ] && [ "$ANYVERSION" != "yes" ]; then + echo "You probably do not need this patch," + echo "since your TeX does not seem to be version 3.0." + echo "If you insist on applying the patch, run $0" + echo "again with the option \`--dammit'" + exit +fi + +grep -s 'file not found' $TMPDIR/texput.log +if [ 0 = $? ]; then + echo "This patch requires the dummy font metric file \`dummy.tfm'," + echo "which does not seem to be part of your TeX installation." + echo "Please get your TeX maintainer to install \`dummy.tfm'," + echo "then run this script again." + exit +fi +rm $TMPDIR/texput.log + +echo "Patching $dir/texinfo.tex" + +sed -e 's/%%*\\font\\nullfont/\\font\\nullfont/' \ + $dir/texinfo.tex >$TMPDIR/texinfo.tex +mv $dir/texinfo.tex $dir/texinfo.tex-distrib; mv $TMPDIR/texinfo.tex $dir + +if [ 0 = $? ]; then + echo "Patched $dir/texinfo.tex to avoid TeX 3.0 bug." + echo "The original version is saved as $dir/texinfo.tex-distrib." +else + echo "Patch failed. Sorry." +fi +----------------------------------------tex3patch ends + + diff --git a/util/texi-docstring-magic.el b/util/texi-docstring-magic.el new file mode 100644 index 0000000..ab66c91 --- /dev/null +++ b/util/texi-docstring-magic.el @@ -0,0 +1,347 @@ +;; texi-docstring-magic.el -- munge internal docstrings into texi +;; +;; Keywords: lisp, docs, tex +;; Author: David Aspinall <da@dcs.ed.ac.uk> +;; Copyright (C) 1998 David Aspinall +;; Maintainer: David Aspinall <da@dcs.ed.ac.uk> +;; +;; $Id: texi-docstring-magic.el,v 1.3 2007/07/01 21:20:33 karl Exp $ +;; +;; This package is distributed under the terms of the +;; GNU General Public License, Version 3. +;; You should have a copy of the GPL with your version of +;; GNU Emacs or the Texinfo distribution. +;; +;; +;; This package generates Texinfo source fragments from Emacs +;; docstrings. This avoids documenting functions and variables +;; in more than one place, and automatically adds Texinfo markup +;; to docstrings. +;; +;; It relies heavily on you following the Elisp documentation +;; conventions to produce sensible output, check the Elisp manual +;; for details. In brief: +;; +;; * The first line of a docstring should be a complete sentence. +;; * Arguments to functions should be written in upper case: ARG1..ARGN +;; * User options (variables users may want to set) should have docstrings +;; beginning with an asterisk. +;; +;; Usage: +;; +;; Write comments of the form: +;; +;; @c TEXI DOCSTRING MAGIC: my-package-function-or-variable-name +;; +;; In your texi source, mypackage.texi. From within an Emacs session +;; where my-package is loaded, visit mypackage.texi and run +;; M-x texi-docstring-magic to update all of the documentation strings. +;; +;; This will insert @defopt, @deffn and the like underneath the +;; magic comment strings. +;; +;; The default value for user options will be printed. +;; +;; Symbols are recognized if they are defined for faces, functions, +;; or variables (in that order). +;; +;; Automatic markup rules: +;; +;; 1. Indented lines are gathered into @lisp environment. +;; 2. Pieces of text `stuff' or surrounded in quotes marked up with @samp. +;; 3. Words *emphasized* are made @strong{emphasized} +;; 4. Words sym-bol which are symbols become @code{sym-bol}. +;; 5. Upper cased words ARG corresponding to arguments become @var{arg}. +;; In fact, you can any word longer than three letters, so that +;; metavariables can be used easily. +;; FIXME: to escape this, use `ARG' +;; 6. Words 'sym which are lisp-quoted are marked with @code{'sym}. +;; +;; ----- +;; +;; Useful key binding when writing Texinfo: +;; +;; (define-key TeXinfo-mode-map "C-cC-d" 'texi-docstring-magic-insert-magic) +;; +;; ----- +;; +;; Useful enhancements to do: +;; +;; * Use customize properties (e.g. group, simple types) +;; * Look for a "texi-docstring" property for symbols +;; so TeXInfo can be defined directly in case automatic markup +;; goes badly wrong. +;; * Add tags to special comments so that user can specify face, +;; function, or variable binding for a symbol in case more than +;; one binding exists. +;; +;; ------ + +(defun texi-docstring-magic-splice-sep (strings sep) + "Return concatenation of STRINGS spliced together with separator SEP." + (let (str) + (while strings + (setq str (concat str (car strings))) + (if (cdr strings) + (setq str (concat str sep))) + (setq strings (cdr strings))) + str)) + +(defconst texi-docstring-magic-munge-table + '(;; 1. Indented lines are gathered into @lisp environment. + ("\\(^.*\\S-.*$\\)" + t + (let + ((line (match-string 0 docstring))) + (if (eq (char-syntax (string-to-char line)) ?\ ) + ;; whitespace + (if in-quoted-region + line + (setq in-quoted-region t) + (concat "@lisp\n" line)) + ;; non-white space + (if in-quoted-region + (progn + (setq in-quoted-region nil) + (concat "@end lisp\n" line)) + line)))) + ;; 2. Pieces of text `stuff' or surrounded in quotes + ;; are marked up with @samp. NB: Must be backquote + ;; followed by forward quote for this to work. + ;; Can't use two forward quotes else problems with + ;; symbols. + ;; Odd hack: because ' is a word constituent in text/texinfo + ;; mode, putting this first enables the recognition of args + ;; and symbols put inside quotes. + ("\\(`\\([^']+\\)'\\)" + t + (concat "@samp{" (match-string 2 docstring) "}")) + ;; 3. Words *emphasized* are made @strong{emphasized} + ("\\(\\*\\(\\w+\\)\\*\\)" + t + (concat "@strong{" (match-string 2 docstring) "}")) + ;; 4. Words sym-bol which are symbols become @code{sym-bol}. + ;; Must have at least one hyphen to be recognized, + ;; terminated in whitespace, end of line, or punctuation. + ;; (Only consider symbols made from word constituents + ;; and hyphen. + ("\\(\\(\\w+\\-\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)" + (or (boundp (intern (match-string 2 docstring))) + (fboundp (intern (match-string 2 docstring)))) + (concat "@code{" (match-string 2 docstring) "}" + (match-string 4 docstring))) + ;; 5. Upper cased words ARG corresponding to arguments become + ;; @var{arg} + ;; In fact, include any word so long as it is more than 3 characters + ;; long. (Comes after symbols to avoid recognizing the + ;; lowercased form of an argument as a symbol) + ;; FIXME: maybe we don't want to downcase stuff already + ;; inside @samp + ;; FIXME: should - terminate? should _ be included? + ("\\([A-Z0-9\\-]+\\)\\(/\\|\)\\|}\\|\\s-\\|\\s.\\|$\\)" + (or (> (length (match-string 1 docstring)) 3) + (member (downcase (match-string 1 docstring)) args)) + (concat "@var{" (downcase (match-string 1 docstring)) "}" + (match-string 2 docstring))) + + ;; 6. Words 'sym which are lisp quoted are + ;; marked with @code. + ("\\(\\(\\s-\\|^\\)'\\(\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)" + t + (concat (match-string 2 docstring) + "@code{'" (match-string 3 docstring) "}" + (match-string 5 docstring))) + ;; 7,8. Clean up for @lisp environments left with spurious newlines + ;; after 1. + ("\\(\\(^\\s-*$\\)\n@lisp\\)" t "@lisp") + ("\\(\\(^\\s-*$\\)\n@end lisp\\)" t "@end lisp")) + "Table of regexp matches and replacements used to markup docstrings. +Format of table is a list of elements of the form + (regexp predicate replacement-form) +If regexp matches and predicate holds, then replacement-form is +evaluated to get the replacement for the match. +predicate and replacement-form can use variables arg, +and forms such as (match-string 1 docstring) +Match string 1 is assumed to determine the +length of the matched item, hence where parsing restarts from. +The replacement must cover the whole match (match string 0), +including any whitespace included to delimit matches.") + + +(defun texi-docstring-magic-munge-docstring (docstring args) + "Markup DOCSTRING for texi according to regexp matches." + (let ((case-fold-search nil)) + (dolist (test texi-docstring-magic-munge-table docstring) + (let ((regexp (nth 0 test)) + (predicate (nth 1 test)) + (replace (nth 2 test)) + (i 0) + in-quoted-region) + + (while (and + (< i (length docstring)) + (string-match regexp docstring i)) + (setq i (match-end 1)) + (if (eval predicate) + (let* ((origlength (- (match-end 0) (match-beginning 0))) + (replacement (eval replace)) + (newlength (length replacement))) + (setq docstring + (replace-match replacement t t docstring)) + (setq i (+ i (- newlength origlength)))))) + (if in-quoted-region + (setq docstring (concat docstring "\n@end lisp")))))) + ;; Force a new line after (what should be) the first sentence, + ;; if not already a new paragraph. + (let* + ((pos (string-match "\n" docstring)) + (needscr (and pos + (not (string= "\n" + (substring docstring + (1+ pos) + (+ pos 2))))))) + (if (and pos needscr) + (concat (substring docstring 0 pos) + "@*\n" + (substring docstring (1+ pos))) + docstring))) + +(defun texi-docstring-magic-texi (env grp name docstring args &optional endtext) + "Make a texi def environment ENV for entity NAME with DOCSTRING." + (concat "@def" env (if grp (concat " " grp) "") " " name + " " + (texi-docstring-magic-splice-sep args " ") + ;; " " + ;; (texi-docstring-magic-splice-sep extras " ") + "\n" + (texi-docstring-magic-munge-docstring docstring args) + "\n" + (or endtext "") + "@end def" env "\n")) + +(defun texi-docstring-magic-format-default (default) + "Make a default value string for the value DEFAULT. +Markup as @code{stuff} or @lisp stuff @end lisp." + (let ((text (format "%S" default))) + (concat + "\nThe default value is " + (if (string-match "\n" text) + ;; Carriage return will break @code, use @lisp + (if (stringp default) + (concat "the string: \n@lisp\n" default "\n@end lisp\n") + (concat "the value: \n@lisp\n" text "\n@end lisp\n")) + (concat "@code{" text "}.\n"))))) + + +(defun texi-docstring-magic-texi-for (symbol) + (cond + ;; Faces + ((find-face symbol) + (let* + ((face symbol) + (name (symbol-name face)) + (docstring (or (face-doc-string face) + "Not documented.")) + (useropt (eq ?* (string-to-char docstring)))) + ;; Chop off user option setting + (if useropt + (setq docstring (substring docstring 1))) + (texi-docstring-magic-texi "fn" "Face" name docstring nil))) + ((fboundp symbol) + ;; Functions. + ;; We don't handle macros, aliases, or compiled fns properly. + (let* + ((function symbol) + (name (symbol-name function)) + (docstring (or (documentation function) + "Not documented.")) + (def (symbol-function function)) + (argsyms (cond ((eq (car-safe def) 'lambda) + (nth 1 def)))) + (args (mapcar 'symbol-name argsyms))) + (if (commandp function) + (texi-docstring-magic-texi "fn" "Command" name docstring args) + (texi-docstring-magic-texi "un" nil name docstring args)))) + ((boundp symbol) + ;; Variables. + (let* + ((variable symbol) + (name (symbol-name variable)) + (docstring (or (documentation-property variable + 'variable-documentation) + "Not documented.")) + (useropt (eq ?* (string-to-char docstring))) + (default (if useropt + (texi-docstring-magic-format-default + (default-value symbol))))) + ;; Chop off user option setting + (if useropt + (setq docstring (substring docstring 1))) + (texi-docstring-magic-texi + (if useropt "opt" "var") nil name docstring nil default))) + (t + (error "Don't know anything about symbol %s" (symbol-name symbol))))) + +(defconst texi-docstring-magic-comment + "@c TEXI DOCSTRING MAGIC:" + "Magic string in a texi buffer expanded into @defopt, or @deffn.") + +(defun texi-docstring-magic () + "Update all texi docstring magic annotations in buffer." + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((magic (concat "^" + (regexp-quote texi-docstring-magic-comment) + "\\s-*\\(\\(\\w\\|\\-\\)+\\)$")) + p + symbol) + (while (re-search-forward magic nil t) + (setq symbol (intern (match-string 1))) + (forward-line) + (setq p (point)) + ;; If comment already followed by an environment, delete it. + (if (and + (looking-at "@def\\(\\w+\\)\\s-") + (search-forward (concat "@end def" (match-string 1)) nil t)) + (progn + (forward-line) + (delete-region p (point)))) + (insert + (texi-docstring-magic-texi-for symbol)))))) + +(defun texi-docstring-magic-face-at-point () + (ignore-errors + (let ((stab (syntax-table))) + (unwind-protect + (save-excursion + (set-syntax-table emacs-lisp-mode-syntax-table) + (or (not (zerop (skip-syntax-backward "_w"))) + (eq (char-syntax (char-after (point))) ?w) + (eq (char-syntax (char-after (point))) ?_) + (forward-sexp -1)) + (skip-chars-forward "'") + (let ((obj (read (current-buffer)))) + (and (symbolp obj) (find-face obj) obj))) + (set-syntax-table stab))))) + +(defun texi-docstring-magic-insert-magic (symbol) + (interactive + (let* ((v (or (variable-at-point) + (function-at-point) + (texi-docstring-magic-face-at-point))) + (val (let ((enable-recursive-minibuffers t)) + (completing-read + (if v + (format "Magic docstring for symbol (default %s): " v) + "Magic docstring for symbol: ") + obarray '(lambda (sym) + (or (boundp sym) + (fboundp sym) + (find-face sym))) + t nil 'variable-history)))) + (list (if (equal val "") v (intern val))))) + (insert "\n" texi-docstring-magic-comment " " (symbol-name symbol))) + + +(provide 'texi-docstring-magic) diff --git a/util/texi2dvi b/util/texi2dvi new file mode 100755 index 0000000..18b2214 --- /dev/null +++ b/util/texi2dvi @@ -0,0 +1,1792 @@ +#! /bin/sh +# texi2dvi --- produce DVI (or PDF) files from Texinfo (or (La)TeX) sources. +# $Id: texi2dvi,v 1.135 2008/09/18 18:46:01 karl Exp $ +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, +# or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Original author: Noah Friedman. +# +# Please send bug reports, etc. to bug-texinfo@gnu.org. +# If possible, please send a copy of the output of the script called with +# the `--debug' option when making a bug report. + +test -f /bin/ksh && test -z "$RUNNING_KSH" \ + && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \ + && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; } +unset RUNNING_KSH + +# No failure shall remain unpunished. +set -e + +# This string is expanded by rcs automatically when this file is checked out. +rcs_revision='$Revision: 1.135 $' +rcs_version=`set - $rcs_revision; echo $2` +program=`echo $0 | sed -e 's!.*/!!'` + +build_mode=${TEXI2DVI_BUILD_MODE:-local} +build_dir=${TEXI2DVI_BUILD_DIRECTORY:-.} + +# Initialize variables for option overriding and otherwise. +# Don't use `unset' since old bourne shells don't have this command. +# Instead, assign them an empty value. +action=compile +batch=false # true for batch mode +debug=false +escape="\\" +expand= # t for expansion via makeinfo +includes= +line_error=true # Pass --file-line-error to TeX. +no_line_error=false # absolutely do not pass --file-line-error to TeX +oname= # --output +out_lang=dvi +quiet=false # by default let the tools' message be displayed +recode=false +set_language= +src_specials= +textra= # Extra TeX commands to insert in the input file. +txiprereq=19990129 # minimum texinfo.tex version with macro expansion +verb=false # true for verbose mode +translate_file= # name of charset translation file +recode_from= # if not empty, recode from this encoding to @documentencoding + +orig_pwd=`pwd` + +# We have to initialize IFS to space tab newline since we save and +# restore IFS and apparently POSIX allows stupid/broken behavior with +# empty-but-set IFS. +# http://lists.gnu.org/archive/html/automake-patches/2006-05/msg00008.html +# We need space, tab and new line, in precisely that order. And don't leave +# trailing blanks. +space=' ' +tab=' ' +newline=' +' +IFS="$space$tab$newline" + +# In case someone pedantic insists on using grep -E. +: ${EGREP=egrep} + +# Systems which define $COMSPEC or $ComSpec use semicolons to separate +# directories in TEXINPUTS -- except for Cygwin et al., where COMSPEC +# might be inherited, but : is used. +if test -n "$COMSPEC$ComSpec" \ + && uname | $EGREP -iv 'cygwin|mingw|djgpp' >/dev/null; then + path_sep=";" +else + path_sep=":" +fi + +# Pacify verbose cds. +CDPATH=${ZSH_VERSION+.}$path_sep + +# If $TEX is set to a directory, don't use it. +test -n "$TEX" && test -d "$TEX" && unset TEX + +# +## --------------------- ## +## Auxiliary functions. ## +## --------------------- ## + +# In case `local' is not supported by the shell, provide a function +# that simulates it by simply performing the assignments. This means +# that we must not expect `local' to work, i.e., we must not (i) rely +# on it during recursion, and (ii) have two local declarations of the +# same variable. (ii) is easy to check statically, and our test suite +# does make sure there is never twice a static local declaration of a +# variable. (i) cannot be checked easily, so just be careful. +# +# Note that since we might use a function simulating `local', we can +# no longer rely on the fact that no IFS-splitting is performed. So, +# while +# +# foo=$bar +# +# is fine (no IFS-splitting), never write +# +# local foo=$bar +# +# but rather +# +# local foo="$bar" +( + foo=bar + test_local () { + local foo=foo + } + test_local + test $foo = bar +) || local () { + case $1 in + *=*) eval "$1";; + esac +} + + +# cd_orig +# ------- +# Return to the original directory. +cd_orig () +{ + # In case $orig_pwd is on a different drive (for DOS). + cd / + + # Return to the original directory so that + # - the next file is processed in correct conditions + # - the temporary file can be removed + cd "$orig_pwd" || exit 1 +} + +# func_dirname FILE +# ----------------- +# Return the directory part of FILE. +func_dirname () +{ + dirname "$1" 2>/dev/null \ + || { echo "$1" | sed 's!/[^/]*$!!;s!^$!.!'; } +} + + +# absolute NAME -> ABS-NAME +# ------------------------- +# Return an absolute path to NAME. +absolute () +{ + case $1 in + [\\/]* | ?:[\\/]*) + # Absolute paths don't need to be expanded. + echo "$1" + ;; + *) local slashes + slashes=`echo "$1" | sed -n 's,.*[^/]\(/*\)$,\1,p'` + local rel + rel=$orig_pwd/`func_dirname "$1"` + if test -d "$rel"; then + (cd "$rel" 2>/dev/null && + local n + n=`pwd`/`basename "$1"`"$slashes" + echo "$n") + else + error 1 "not a directory: $rel" + fi + ;; + esac +} + + +# ensure_dir DIR1 DIR2... +# ----------------------- +# Make sure the directories exist. +ensure_dir () +{ + for dir + do + test -d "$dir" \ + || mkdir "$dir" \ + || error 1 "cannot create directory: $dir" + done +} + + +# error EXIT_STATUS LINE1 LINE2... +# -------------------------------- +# Report an error and exit with failure if EXIT_STATUS is non null. +error () +{ + local s="$1" + shift + report "$@" + if test "$s" != 0; then + exit $s + fi +} + + +# findprog PROG +# ------------- +# Return true if PROG is somewhere in PATH, else false. +findprog () +{ + local saveIFS="$IFS" + IFS=$path_sep # break path components at the path separator + for dir in $PATH; do + IFS=$saveIFS + # The basic test for an executable is `test -f $f && test -x $f'. + # (`test -x' is not enough, because it can also be true for directories.) + # We have to try this both for $1 and $1.exe. + # + # Note: On Cygwin and DJGPP, `test -x' also looks for .exe. On Cygwin, + # also `test -f' has this enhancement, bot not on DJGPP. (Both are + # design decisions, so there is little chance to make them consistent.) + # Thusly, it seems to be difficult to make use of these enhancements. + # + if { test -f "$dir/$1" && test -x "$dir/$1"; } || + { test -f "$dir/$1.exe" && test -x "$dir/$1.exe"; }; then + return 0 + fi + done + return 1 +} + +# report LINE1 LINE2... +# --------------------- +# Report some information on stderr. +report () +{ + for i in "$@" + do + echo >&2 "$0: $i" + done +} + + +# run COMMAND-LINE +# ---------------- +# Run the COMMAND-LINE verbosely, and catching errors as failures. +run () +{ + verbose "Running $@" + "$@" 2>&5 1>&2 || + error 1 "$1 failed" +} + + +# usage +# ----- +# Display usage and exit successfully. +usage () +{ + # We used to simply have `echo "$usage"', but coping with the + # changing behavior of `echo' is much harder than simply using a + # here-doc. + # + # echo '\noto' echo '\\noto' echo -e '\\noto' + # bash 3.1 \noto \\noto \noto + # bash 3.2 %oto \noto -e \noto + # + # where % denotes the eol character. + cat <<EOF +Usage: $program [OPTION]... FILE... + +Run each Texinfo or (La)TeX FILE through TeX in turn until all +cross-references are resolved, building all indices. The directory +containing each FILE is searched for included files. The suffix of FILE +is used to determine its language ((La)TeX or Texinfo). To process +(e)plain TeX files, set the environment variable LATEX=tex. + +In order to make texi2dvi a drop-in replacement of TeX/LaTeX in AUC-TeX, +the FILE may also be composed of the following simple TeX commands. + \`\\input{FILE}' the actual file to compile + \`\\nonstopmode' same as --batch + +Makeinfo is used to perform Texinfo macro expansion before running TeX +when needed. + +General options: + -b, --batch no interaction + -D, --debug turn on shell debugging (set -x) + -h, --help display this help and exit successfully + -o, --output=OFILE leave output in OFILE (implies --clean); + only one input FILE may be specified in this case + -q, --quiet no output unless errors (implies --batch) + -s, --silent same as --quiet + -v, --version display version information and exit successfully + -V, --verbose report on what is done + +TeX tuning: + -@ use @input instead of \input for preloaded Texinfo + --dvi output a DVI file [default] + --dvipdf output a PDF file via DVI (using dvipdf) + -e, -E, --expand force macro expansion using makeinfo + -I DIR search DIR for Texinfo files + -l, --language=LANG specify LANG for FILE, either latex or texinfo + --no-line-error do not pass --file-line-error to TeX + -p, --pdf use pdftex or pdflatex for processing + -r, --recode call recode before TeX to translate input + --recode-from=ENC recode from ENC to the @documentencoding + --src-specials pass --src-specials to TeX + -t, --command=CMD insert CMD in copy of input file + or --texinfo=CMD multiple values accumulate + --translate-file=FILE use given charset translation file for TeX + +Build modes: + --build=MODE specify the treatment of auxiliary files [$build_mode] + --tidy same as --build=tidy + -c, --clean same as --build=clean + --build-dir=DIR specify where the tidy compilation is performed; + implies --tidy; + defaults to TEXI2DVI_BUILD_DIRECTORY [$build_dir] + --mostly-clean remove the auxiliary files and directories + but not the output + +The MODE specifies where the TeX compilation takes place, and, as a +consequence, how auxiliary files are treated. The build mode +can also be set using the environment variable TEXI2DVI_BUILD_MODE. + +Valid MODEs are: + \`local' compile in the current directory, leaving all the auxiliary + files around. This is the traditional TeX use. + \`tidy' compile in a local *.t2d directory, where the auxiliary files + are left. Output files are copied back to the original file. + \`clean' same as \`tidy', but remove the auxiliary directory afterwards. + Every compilation therefore requires the full cycle. + +Using the \`tidy' mode brings several advantages: + - the current directory is not cluttered with plethora of temporary files. + - clutter can be even reduced using --build-dir=dir: all the *.t2d + directories are stored there. + - clutter can be reduced to zero using, e.g., --build-dir=/tmp/\$USER.t2d + or --build-dir=\$HOME/.t2d. + - the output file is updated after every succesful TeX run, for + sake of concurrent visualization of the output. In a \`local' build + the viewer stops during the whole TeX run. + - if the compilation fails, the previous state of the output file + is preserved. + - PDF and DVI compilation are kept in separate subdirectories + preventing any possibility of auxiliary file incompatibility. + +On the other hand, because \`tidy' compilation takes place in another +directory, occasionally TeX won't be able to find some files (e.g., when +using \\graphicspath): in that case use -I to specify the additional +directories to consider. + +The values of the BIBTEX, LATEX (or PDFLATEX), MAKEINDEX, MAKEINFO, +TEX (or PDFTEX), TEXINDEX, and THUMBPDF environment variables are used +to run those commands, if they are set. Any CMD strings are added +after @setfilename for Texinfo input, in the first line for LaTeX input. + +Email bug reports to <bug-texinfo@gnu.org>, +general questions and discussion to <help-texinfo@gnu.org>. +Texinfo home page: http://www.gnu.org/software/texinfo/ +EOF + exit 0 +} + + +# verbose WORD1 WORD2 +# ------------------- +# Report some verbose information. +verbose () +{ + if $verb; then + echo >&2 "$0: $@" + fi +} + + +# version +# ------- +# Display version info and exit succesfully. +version () +{ + cat <<EOF +texi2dvi (GNU Texinfo 4.13) $rcs_version + +Copyright (C) 2008 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. +EOF + exit 0 +} + + +## ---------------- ## +## Handling lists. ## +## ---------------- ## + + +# list_append LIST-NAME ELEM +# -------------------------- +# Set LIST-NAME to its former contents, with ELEM appended. +list_append () +{ + local la_l="$1" + shift + eval set X \$$la_l "$@" + shift + eval $la_l=\""$@"\" +} + + +# list_concat_dirs LIST-NAME DIR-LIST +# ----------------------------------- +# Append to LIST-NAME all the components (included empty) from +# the $path_sep separated list DIR-LIST. Make the paths absolute. +list_concat_dirs () +{ + local lcd_list="$1" + # Empty path components are meaningful to tex. We rewrite them as + # `EMPTY' so they don't get lost when we split on $path_sep. + # Hopefully no one will have an actual directory named EMPTY. + local replace_EMPTY="-e 's/^$path_sep/EMPTY$path_sep/g' \ + -e 's/$path_sep\$/${path_sep}EMPTY/g' \ + -e 's/$path_sep$path_sep/${path_sep}EMPTY:/g'" + save_IFS=$IFS + IFS=$path_sep + set x `echo "$2" | eval sed $replace_EMPTY`; shift + IFS=$save_IFS + local dir + for dir + do + case $dir in + EMPTY) + list_append $lcd_list "" + ;; + *) + if test -d $dir; then + dir=`absolute "$dir"` + list_append $lcd_list "$dir" + fi + ;; + esac + done +} + + +# list_prefix LIST-NAME SEP -> STRING +# ----------------------------------- +# Return a string that is composed of the LIST-NAME with each item +# preceded by SEP. +list_prefix () +{ + local lp_p="$2" + eval set X \$$1 + shift + local lp_res + for i + do + lp_res="$lp_res \"$lp_p\" \"$i\"" + done + echo "$lp_res" +} + +# list_infix LIST-NAME SEP -> STRING +# ---------------------------------- +# Same as list_prefix, but a separator. +list_infix () +{ + eval set X \$$1 + shift + local la_IFS="$IFS" + IFS=$path_sep + echo "$*" + IFS=$la_IFS +} + +# list_dir_to_abs LIST-NAME +# ------------------------- +# Convert the list to using only absolute dir names. +# Currently unused, but should replace absolute_filenames some day. +list_dir_to_abs () +{ + local ld_l="$1" + eval set X \$$ld_l + shift + local ld_res + for dir + do + dir=`absolute "$dir"` + test -d "$dir" || continue + ld_res="$ld_res \"$dir\"" + done + set X $ld_res; shift + eval $ld_l=\"$@\" +} + + +## ------------------------------ ## +## Language auxiliary functions. ## +## ------------------------------ ## + +# out_lang_tex +# ------------ +# Return the tex output language (DVI or PDF) for $OUT_LANG. +out_lang_tex () +{ + case $out_lang in + dvi | ps | dvipdf ) echo dvi;; + pdf ) echo $out_lang;; + html | info | text ) echo $out_lang;; + *) error 1 "$0: invalid out_lang: $1";; + esac +} + + +# out_lang_ext +# ------------ +# Return the extension for $OUT_LANG. +out_lang_ext () +{ + case $out_lang in + dvipdf ) echo pdf;; + dvi | html | info | pdf | ps | text ) echo $out_lang;; + *) error 1 "$0: invalid out_lang: $1";; + esac +} + + +## ------------------------- ## +## TeX auxiliary functions. ## +## ------------------------- ## + +# Save TEXINPUTS so we can construct a new TEXINPUTS path for each file. +# Likewise for bibtex and makeindex. +tex_envvars="BIBINPUTS BSTINPUTS DVIPSHEADERS INDEXSTYLE MFINPUTS MPINPUTS \ +TEXINPUTS TFMFONTS" +for var in $tex_envvars; do + eval ${var}_orig=\$$var + export $var +done + + +# absolute_filenames TEX-PATH -> TEX-PATH +# --------------------------------------- +# Convert relative paths to absolute paths, so we can run in another +# directory (e.g., in tidy build mode, or during the macro-support +# detection). Prepend ".". +absolute_filenames () +{ + # Empty path components are meaningful to tex. We rewrite them as + # `EMPTY' so they don't get lost when we split on $path_sep. + # Hopefully no one will have an actual directory named EMPTY. + local replace_empty="-e 's/^$path_sep/EMPTY$path_sep/g' \ + -e 's/$path_sep\$/${path_sep}EMPTY/g' \ + -e 's/$path_sep$path_sep/${path_sep}EMPTY:/g'" + local res + res=`echo "$1" | eval sed $replace_empty` + save_IFS=$IFS + IFS=$path_sep + set x $res; shift + res=. + for dir + do + case $dir in + EMPTY) + res=$res$path_sep + ;; + *) + if test -d "$dir"; then + res=$res$path_sep`absolute "$dir"` + else + # Even if $dir is not a directory, preserve it in the path. + # It might contain metacharacters that TeX will expand in + # turn, e.g., /some/path/{a,b,c}. This will not get the + # implicit absolutification of the path, but we can't help that. + res=$res$path_sep$dir + fi + ;; + esac + done + echo "$res" +} + + +# output_base_name FILE +# --------------------- +# The name of FILE, possibly renamed to satisfy --output. +output_base_name () +{ + case $oname in + '') echo "$1";; + *) local out_noext + out_noext=`echo "$oname" | sed 's/\.[^.]*$//'` + local file_ext + file_ext=`echo "$1" | sed 's/^.*\.//'` + echo "$out_noext.$file_ext" + ;; + esac +} + + +# move_to_dest FILE... +# -------------------- +# Move FILE to the place where the user expects it. Truly move it, that +# is, it must not remain in its build location unless that is also the +# output location. (Otherwise it might appear as an extra file in make +# distcheck.) +# +# FILE can be the principal output (in which case -o directly applies), or +# an auxiliary file with the same base name. +move_to_dest () +{ + local dest + local destfile + local destdir + local destbase + local sourcedir + local sourcebase + + for file + do + case $tidy:$oname in + true:) dest=$orig_pwd;; + false:) dest=;; + *:*) dest=`output_base_name "$file"`;; + esac + if test ! -f "$file"; then + error 1 "no such file or directory: $file" + fi + if test -n "$dest"; then + # We need to know whether $dest is a directory. + if test -d "$dest"; then + destdir=$dest + destfile=$dest/$file + else + destdir="`dirname $dest`" + destfile=$dest + fi + # We want to compare the source location and the output location, + # and if they are different, do the move. But if they are the + # same, we must preserve the source. Since we can't assume + # stat(1) or test -ef is available, resort to comparing the + # directory names, canonicalized with pwd. We can't use cmp -s + # since the output file might not actually change from run to run; + # e.g., TeX DVI output is timestamped to only the nearest minute. + destdir=`cd $destdir && pwd` + destbase=`basename $destfile` + # + sourcedir=`dirname $file` + sourcedir=`cd $sourcedir && pwd` + sourcebase=`basename $file` + # + if test "$sourcedir/$sourcebase" != "$destdir/$destbase"; then + verbose "Moving $file to $destfile" + rm -f "$destfile" + mv "$file" "$destfile" + fi + fi + done +} + + +## --------------------- ## +## Managing xref files. ## +## --------------------- ## + +# aux_file_p FILE +# --------------- +# Return with success with FILE is an aux file. +aux_file_p () +{ + test -f "$1" || return 1 + case $1 in + *.aux) return 0;; + *) return 1;; + esac +} + +# bibaux_file_p FILE +# ------------------ +# Return with success with FILE is an aux file containing citation +# requests. +bibaux_file_p () +{ + test -s "$1" || return 1 + if (grep '^\\bibstyle[{]' "$1" \ + && grep '^\\bibdata[{]' "$1" \ + ## The following line is suspicious: fails when there + ## are citations in sub aux files. We need to be + ## smarter in this case. + ## && grep '^\\citation[{]' "$f" + ) >&6 2>&1; + then + return 0 + fi + return 1 +} + +# index_file_p FILE +# ----------------- +# Return with success with FILE is an index file. +# When index.sty is used, there is a space before the brace. +index_file_p () +{ + test -f "$1" || return 1 + case `sed '1q' "$1"` in + "\\entry{"*|"\\indexentry{"*|"\\indexentry {"*) return 0;; + *) return 1;; + esac +} + +# xref_file_p FILE +# ---------------- +# Return with success if FILE is an xref file (indexes, tables and lists). +xref_file_p () +{ + test -f "$1" || return 1 + # If the file is not suitable to be an index or xref file, don't + # process it. It's suitable if the first character is a + # backslash or right quote or at, as long as the first line isn't + # \input texinfo. + case `sed '1q' "$1"` in + "\\input texinfo"*) return 1;; + [\\''@]*) return 0;; + *) return 1;; + esac +} + + +# generated_files_get FILENAME-NOEXT [PREDICATE-FILTER] +# ----------------------------------------------------- +# Return the list of files generated by the TeX compilation of FILENAME-NOEXT. +generated_files_get () +{ + local filter=true + if test -n "$2"; then + filter=$2 + fi + + # Gather the files created by TeX. + ( + if test -f "$1.log"; then + sed -n -e "s,^\\\\openout.* = \`\\(.*\\)'\\.,\\1,p" "$1.log" + fi + echo "$1.log" + ) | + # Depending on these files, infer outputs from other tools. + while read file; do + echo $file + case $in_lang in + texinfo) + # texindex: texinfo.cp -> texinfo.cps + if index_file_p $file; then + echo ${file}s + fi + ;; + latex) + if aux_file_p $file; then + # bibtex: *.aux -> *.bbl and *.blg. + echo $file | sed 's/^\(.*\)\.aux$/\1.bbl/' + echo $file | sed 's/^\(.*\)\.aux$/\1.blg/' + # -recorder: .fls + echo $file | sed 's/^\(.*\)\.aux$/\1.fls/' + fi + ;; + esac + done | + # Filter existing files matching the criterion. + # + # With an input file name containing a space, this produces a + # "command not found" message (and filtering is ineffective). + # The situation with a newline is presumably even worse. + while read file; do + if $filter "$file"; then + echo $file + fi + done | + sort | + # Some files are opened several times, e.g., listings.sty's *.vrb. + uniq +} + + +# xref_files_save +# --------------- +# Save the xref files. +xref_files_save () +{ + # Save copies of auxiliary files for later comparison. + xref_files_orig=`generated_files_get "$in_noext" xref_file_p` + if test -n "$xref_files_orig"; then + verbose "Backing up xref files: $xref_files_orig" + # The following line improves `cp $xref_files_orig "$work_bak"' + # by preserving the directory parts. Think of + # cp chap1/main.aux chap2/main.aux $work_bak. + # + # Users may have, e.g., --keep-old-files. Don't let this interfere. + # (Don't use unset for the sake of ancient shells.) + TAR_OPTIONS=; export TAR_OPTIONS + tar cf - $xref_files_orig | (cd "$work_bak" && tar xf -) + fi +} + + +# xref_files_changed +# ------------------ +# Whether the xref files were changed since the previous run. +xref_files_changed () +{ + # LaTeX (and the package changebar) report in the LOG file if it + # should be rerun. This is needed for files included from + # subdirs, since texi2dvi does not try to compare xref files in + # subdirs. Performing xref files test is still good since LaTeX + # does not report changes in xref files. + if grep "Rerun to get" "$in_noext.log" >&6 2>&1; then + return 0 + fi + + # If old and new lists don't at least have the same file list, + # then one file or another has definitely changed. + xref_files_new=`generated_files_get "$in_noext" xref_file_p` + verbose "Original xref files = $xref_files_orig" + verbose "New xref files = $xref_files_new" + if test "x$xref_files_orig" != "x$xref_files_new"; then + return 0 + fi + + # Compare each file until we find a difference. + for this_file in $xref_files_new; do + verbose "Comparing xref file `echo $this_file | sed 's|\./||g'` ..." + # cmp -s returns nonzero exit status if files differ. + if cmp -s "$this_file" "$work_bak/$this_file"; then :; else + verbose "xref file `echo $this_file | sed 's|\./||g'` differed ..." + if $debug; then + diff -u "$work_bak/$this_file" "$this_file" + fi + return 0 + fi + done + + # No change. + return 1 +} + + + +## ----------------------- ## +## Running the TeX suite. ## +## ----------------------- ## + + + +# run_tex () +# ---------- +# Run TeX as "$tex $in_input", taking care of errors and logs. +run_tex () +{ + case $in_lang:`out_lang_tex` in + latex:dvi) tex=${LATEX:-latex};; + latex:pdf) tex=${PDFLATEX:-pdflatex};; + texinfo:dvi) + # MetaPost also uses the TEX environment variable. If the user + # has set TEX=latex for that reason, don't bomb out. + case $TEX in + *latex) tex=tex;; # don't bother trying to find etex + *) tex=$TEX + esac;; + texinfo:pdf) tex=$PDFTEX;; + + *) error 1 "$0: $out_lang not supported for $in_lang";; + esac + + # Beware of aux files in subdirectories that require the + # subdirectory to exist. + case $in_lang:$tidy in + latex:true) + sed -n 's|^[ ]*\\include{\(.*\)/.*}.*|\1|p' "$in_input" | + sort -u | + while read d + do + ensure_dir "$work_build/$d" + done + ;; + esac + + # Note that this will be used via an eval: quote properly. + local cmd="$tex" + + # If possible, make TeX report error locations in GNU format. + if test "${tex_help:+set}" != set; then + # Go to a temporary directory to try --help, since old versions that + # don't accept --help will generate a texput.log. + tex_help_dir=$t2ddir/tex_help + ensure_dir "$tex_help_dir" + tex_help=`cd "$tex_help_dir" >&6 && $tex --help </dev/null 2>&1` + fi + if $no_line_error; then :; else + # The mk program and perhaps others want to parse TeX's + # original error messages. + case $line_error:$tex_help in + true:*file-line-error*) cmd="$cmd --file-line-error";; + esac + fi + + # Tell TeX about TCX file, if specified. + test -n "$translate_file" && cmd="$cmd --translate-file=$translate_file" + + # Tell TeX to make source specials (for backtracking from output to + # source, given a sufficiently smart editor), if specifed. + test -n "$src_specials" && cmd="$cmd $src_specials" + + # Tell TeX to be batch if requested. + if $batch; then + # \batchmode does not show terminal output at all, so we don't + # want that. And even in batch mode, TeX insists on having input + # from the user. Close its stdin to make it impossible. + cmd="$cmd </dev/null '${escape}nonstopmode' '${escape}input'" + fi + + # we'd like to handle arbitrary input file names, such as a~b.tex. + # This isn't a general way to do it :), though it does work, kind of. + # cmd="$cmd '${escape}catcode126=12 \input '" + + # TeX's \input does not (easily or reliably) support whitespace + # characters or other special characters in file names. Our intensive + # use of absolute file names makes this worse: the enclosing directory + # names may include white spaces. Improve the situation using a + # symbolic link to the filename in the current directory, in tidy mode + # only. Do not alter in_input. + # + # The filename is almost always tokenized using plain TeX conventions + # (the exception would be if the user made a texinfo.fmt file). Not + # all the plain TeX special characters cause trouble, but there's no + # harm in making the link. + # + case $tidy:`func_dirname "$in_input"` in + true:*["$space$tab$newline\"#\$%\\^_{}"]*) + _run_tex_file_name=`basename "$in_input"` + if test ! -f "$_run_tex_file_name"; then + # It might not be a file, clear it. + run rm -f "$_run_tex_file_name" + run ln -s "$in_input" + fi + cmd="$cmd '$_run_tex_file_name'" + ;; + + *) + cmd="$cmd '$in_input'" + ;; + esac + + verbose "$0: Running $cmd ..." + if eval "$cmd" >&5; then + case $out_lang in + dvi | pdf ) move_to_dest "$in_noext.$out_lang";; + esac + else + error 1 "$tex exited with bad status, quitting." + fi +} + +# run_bibtex () +# ------------- +# Run bibtex on current file. +# - If its input (AUX) exists. +# - If some citations are missing (LOG contains `Citation'). +# or the LOG complains of a missing .bbl +# +# Don't try to be too smart: +# +# 1. Running bibtex only if the bbl file exists and is older than +# the LaTeX file is wrong, since the document might include files +# that have changed. +# +# 3. Because there can be several AUX (if there are \include's), +# but a single LOG, looking for missing citations in LOG is +# easier, though we take the risk to match false messages. +run_bibtex () +{ + case $in_lang in + latex) bibtex=${BIBTEX:-bibtex};; + texinfo) return;; + esac + + # "Citation undefined" is for LaTeX, "Undefined citation" for btxmac.tex. + # The no .aux && \bibdata test is also for btxmac, in case it was the + # first run of a bibtex-using document. Otherwise, it's possible that + # bibtex would never be run. + if test -r "$in_noext.aux" \ + && test -r "$in_noext.log" \ + && (grep 'Warning:.*Citation.*undefined' "$in_noext.log" \ + || grep '.*Undefined citation' "$in_noext.log" \ + || grep 'No file .*\.bbl\.' "$in_noext.log") \ + || (grep 'No \.aux file' "$in_noext.log" \ + && grep '^\\bibdata' "$in_noext.aux") \ + >&6 2>&1; \ + then + for f in `generated_files_get "$in_noext" bibaux_file_p` + do + run $bibtex "$f" + done + fi +} + +# run_index () +# ------------ +# Run texindex (or makeindex) on current index files. If they already +# exist, and after running TeX a first time the index files don't +# change, then there's no reason to run TeX again. But we won't know +# that if the index files are out of date or nonexistent. +run_index () +{ + case $in_lang in + latex) texindex=${MAKEINDEX:-makeindex};; + texinfo) texindex=${TEXINDEX:-texindex};; + esac + index_files=`generated_files_get $in_noext index_file_p` + if test -n "$texindex" && test -n "$index_files"; then + run $texindex $index_files + fi +} + + +# run_thumbpdf () +# --------------- +run_thumbpdf () +{ + if test `out_lang_tex` = pdf \ + && test -r "$in_noext.log" \ + && grep 'thumbpdf\.sty' "$in_noext.log" >&6 2>&1; \ + then + thumbpdf=${THUMBPDF:-thumbpdf} + thumbcmd="$thumbpdf $in_dir/$in_noext" + verbose "Running $thumbcmd ..." + if $thumbcmd >&5; then + run_tex + else + report "$thumbpdf exited with bad status." \ + "Ignoring its output." + fi + fi +} + + +# run_dvipdf FILE.dvi +# ------------------- +# Convert FILE.dvi to FILE.pdf. +run_dvipdf () +{ + # Find which dvi->pdf program is available. + if test -z "$dvipdf"; then + for i in "$DVIPDF" dvipdfmx dvipdfm dvipdf dvi2pdf dvitopdf; + do + if findprog $i; then + dvipdf=$i + fi + done + fi + # These tools have varying interfaces, some 'input output', others + # 'input -o output'. They all seem to accept 'input' only, + # outputting using the expected file name. + run $dvipdf "$1" + if test ! -f `echo "$1" | sed -e 's/\.dvi$/.pdf/'`; then + error 1 "$0: cannot find output file" + fi +} + +# run_tex_suite () +# ---------------- +# Run the TeX tools until a fix point is reached. +run_tex_suite () +{ + # Move to the working directory. + if $tidy; then + verbose "cd $work_build" + cd "$work_build" || exit 1 + fi + + # Count the number of cycles. + local cycle=0 + + while :; do + cycle=`expr $cycle + 1` + verbose "Cycle $cycle for $command_line_filename" + + xref_files_save + + # We run bibtex first, because I can see reasons for the indexes + # to change after bibtex is run, but I see no reason for the + # converse. + run_bibtex + run_index + run_core_conversion + + xref_files_changed || break + done + + # If we were using thumbpdf and producing PDF, then run thumbpdf + # and TeX one last time. + run_thumbpdf + + # Install the result if we didn't already (i.e., if the output is + # dvipdf or ps). + case $out_lang in + dvipdf) + run_dvipdf "$in_noext.`out_lang_tex`" + move_to_dest "$in_noext.`out_lang_ext`" + ;; + ps) + dvips -o "$in_noext.`out_lang_ext`" "$in_noext.`out_lang_tex`" + move_to_dest "$in_noext.`out_lang_ext`" + ;; + esac + + cd_orig +} + +## -------------------------------- ## +## TeX processing auxiliary tools. ## +## -------------------------------- ## + + +# A sed script that preprocesses Texinfo sources in order to keep the +# iftex sections only. We want to remove non TeX sections, and comment +# (with `@c texi2dvi') TeX sections so that makeinfo does not try to +# parse them. Nevertheless, while commenting TeX sections, don't +# comment @macro/@end macro so that makeinfo does propagate them. +# Unfortunately makeinfo --iftex --no-ifinfo doesn't work well enough +# (yet), makeinfo can't parse the TeX commands, so work around with sed. +# +comment_iftex=\ +'/^@tex/,/^@end tex/{ + s/^/@c texi2dvi/ +} +/^@iftex/,/^@end iftex/{ + s/^/@c texi2dvi/ + /^@c texi2dvi@macro/,/^@c texi2dvi@end macro/{ + s/^@c texi2dvi// + } +} +/^@ifnottex/,/^@end ifnottex/{ + s/^/@c (texi2dvi)/ +} +/^@ifinfo/,/^@end ifinfo/{ + /^@node/p + /^@menu/,/^@end menu/p + t + s/^/@c (texi2dvi)/ +} +s/^@ifnotinfo/@c texi2dvi@ifnotinfo/ +s/^@end ifnotinfo/@c texi2dvi@end ifnotinfo/' + +# Uncommenting is simple: Remove any leading `@c texi2dvi'. +uncomment_iftex='s/^@c texi2dvi//' + + +# run_makeinfo () +# --------------- +# Expand macro commands in the original source file using Makeinfo. +# Always use `end' footnote style, since the `separate' style +# generates different output (arguably this is a bug in -E). Discard +# main info output, the user asked to run TeX, not makeinfo. +run_makeinfo () +{ + test $in_lang = texinfo \ + || return 0 + + # Unless required by the user, makeinfo expansion is wanted only + # if texinfo.tex is too old. + if test "$expand" = t; then + makeinfo=${MAKEINFO:-makeinfo} + else + # Check if texinfo.tex performs macro expansion by looking for + # its version. The version is a date of the form YEAR-MO-DA. + # We don't need to use [0-9] to match the digits since anyway + # the comparison with $txiprereq, a number, will fail with non + # digits. + # Run in a temporary directory to avoid leaving files. + version_test_dir=$t2ddir/version_test + ensure_dir "$version_test_dir" + ( + cd "$version_test_dir" + echo '\input texinfo.tex @bye' >txiversion.tex + # Be sure that if tex wants to fail, it is not interactive: + # close stdin. + $TEX txiversion.tex </dev/null >txiversion.out 2>txiversion.err + ) + if test $? != 0; then + cat "$version_test_dir/txiversion.out" + cat "$version_test_dir/txiversion.err" >&2 + error 1 "texinfo.tex appears to be broken, quitting." + fi + eval `sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p' "$version_test_dir/txiversion.out"` + verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..." + if test "$txiprereq" -le "$txiversion" >&6 2>&1; then + makeinfo= + else + makeinfo=${MAKEINFO:-makeinfo} + fi + # As long as we had to run TeX, offer the user this convenience: + if test "$txiformat" = Texinfo; then + escape=@ + fi + fi + + if test -n "$makeinfo"; then + # in_src: the file with macros expanded. + # Use the same basename to generate the same aux file names. + work_src=$workdir/src + ensure_dir "$work_src" + in_src=$work_src/$in_base + local miincludes + miincludes=`list_prefix includes -I` + verbose "Macro-expanding $command_line_filename to $in_src ..." + # eval $makeinfo because it might be defined as something complex + # (running missing) and then we end up with things like '"-I"', + # and "-I" (including the quotes) is not an option name. This + # happens with gettext 0.14.5, at least. + sed "$comment_iftex" "$command_line_filename" \ + | eval $makeinfo --footnote-style=end -I "$in_dir" $miincludes \ + -o /dev/null --macro-expand=- \ + | sed "$uncomment_iftex" >"$in_src" + # Continue only if everything succeeded. + if test $? -ne 0 \ + || test ! -r "$in_src"; then + verbose "Expansion failed, ignored..."; + else + in_input=$in_src + fi + fi +} + +# insert_commands () +# ------------------ +# Used most commonly for @finalout, @smallbook, etc. +insert_commands () +{ + local textra_cmd + case $in_lang in + latex) textra_cmd=1i;; + texinfo) textra_cmd='/^@setfilename/a';; + *) error 1 "internal error, unknown language: $in_lang";; + esac + + if test -n "$textra"; then + # _xtr. The file with the user's extra commands. + work_xtr=$workdir/xtr + in_xtr=$work_xtr/$in_base + ensure_dir "$work_xtr" + verbose "Inserting extra commands: $textra" + sed "$textra_cmd\\ +$textra" "$in_input" >"$in_xtr" + in_input=$in_xtr + fi +} + +# run_recode () +# ------------- +# If this is a Texinfo file with a specified input encoding, and +# recode is available, then recode to plain 7 bit Texinfo. +run_recode () +{ + local from + local to + + if test $in_lang = texinfo; then + pgm='s/^ *@documentencoding *\([^ ][^ ]*\) *$/\1/ + t found + d + :found + q' + encoding=`sed -e "$pgm" "$in_input"` + if $recode && test -n "$encoding" && findprog recode; then + if test -n "$recode_from"; then + from=$recode_from + to=$encoding + else + from=$encoding + to=$texinfo + fi + verbose "Recoding from $from to $to." + # _rcd. The Texinfo file recoded in 7bit. + work_rcd=$workdir/recode + in_rcd=$work_rcd/$in_base + ensure_dir "$work_rcd" + if recode "$encoding..$to" <"$in_input" >"$in_rcd" \ + && test -s "$in_rcd"; then + in_input=$in_rcd + else + verbose "Recoding failed, using original input." + fi + fi + fi +} + +# compute_language FILENAME +# ------------------------- +# Return the short string describing the language in which FILENAME +# is written: `texinfo' or `latex'. +compute_language () +{ + # If the user explicitly specified the language, use that. + # Otherwise, if the first line is \input texinfo, assume it's texinfo. + # Otherwise, guess from the file extension. + if test -n "$set_language"; then + echo $set_language + elif sed 1q "$1" | grep 'input texinfo' >&6; then + echo texinfo + else + # Get the type of the file (latex or texinfo) from the given language + # we just guessed, or from the file extension if not set yet. + case $1 in + *.ltx | *.tex | *.drv | *.dtx) echo latex;; + *) echo texinfo;; + esac + fi +} + + +# run_hevea (MODE) +# ---------------- +# Convert to HTML/INFO/TEXT. +# +# Don't pass `-noiso' to hevea: it's useless in HTML since anyway the +# charset is set to latin1, and troublesome in other modes since +# accented characters loose their accents. +# +# Don't pass `-o DEST' to hevea because in that case it leaves all its +# auxiliary files there too... Too bad, because it means we will need +# to handle images some day. +run_hevea () +{ + local hevea="${HEVEA:-hevea}" + local run_hevea="$hevea" + + case $1 in + html) ;; + text|info) run_hevea="$run_hevea -$1";; + *) error 1 "run_hevea: invalid argument: $1";; + esac + + # Compiling to the tmp directory enables to preserve a previous + # successful compilation. + run_hevea="$run_hevea -fix -O -o '$out_base'" + run_hevea="$run_hevea `list_prefix includes -I` -I '$orig_pwd' " + run_hevea="$run_hevea '$in_input'" + + if $debug; then + run_hevea="$run_hevea -v -v" + fi + + verbose "running $run_hevea" + if eval "$run_hevea" >&5; then + # hevea leaves trailing white spaces, this is annoying. + case $1 in text|info) + perl -pi -e 's/[ \t]+$//g' "$out_base"*;; + esac + case $1 in + html|text) move_to_dest "$out_base";; + info) # There can be foo.info-1, foo.info-2 etc. + move_to_dest "$out_base"*;; + esac + else + error 1 "$hevea exited with bad status, quitting." + fi +} + + +# run_core_conversion () +# ---------------------- +# Run the TeX (or HeVeA). +run_core_conversion () +{ + case $in_lang:`out_lang_tex` in + *:dvi|*:pdf) + run_tex;; + latex:html|latex:text|latex:info) + run_hevea $out_lang;; + *) + error 1 "invalid input/output combination: $in_lang/$out_lang";; + esac +} + + +# compile () +# ---------- +# Run the full compilation chain, from pre-processing to installation +# of the output at its expected location. +compile () +{ + # Source file might include additional sources. + # We want `.:$orig_pwd' before anything else. (We'll add `.:' later + # after all other directories have been turned into absolute paths.) + # `.' goes first to ensure that any old .aux, .cps, + # etc. files in ${directory} don't get used in preference to fresher + # files in `.'. Include orig_pwd in case we are in clean build mode, where + # we've cd'd to a temp directory. + txincludes=`list_infix includes $path_sep` + common="$orig_pwd$path_sep$in_dir$path_sep$txincludes$path_sep" + for var in $tex_envvars; do + eval val="\$common\$${var}_orig" + # Convert relative paths to absolute paths, so we can run in another + # directory (e.g., in clean build mode, or during the macro-support + # detection). ".:" is added here. + val=`absolute_filenames "$val"` + eval $var="\"$val\"" + export $var + eval verbose \"$var=\'\$${var}\'\" + done + + # --expand + run_makeinfo + + # --command, --texinfo + insert_commands + + # --recode + run_recode + + # Run until a fix point is reached. + run_tex_suite +} + + +# remove FILES +# ------------ +remove () +{ + verbose "Removing" "$@" + rm -rf "$@" +} + + +# mostly_clean +# ------------ +# Remove auxiliary files and directories. Changes the current directory. +mostly_clean () +{ + cd_orig + set X "$t2ddir" + shift + $tidy || { + local log="$work_build/$in_noext.log" + set X ${1+"$@"} "$log" `generated_files_get "$work_build/$in_noext"` + shift + } + remove ${1+"$@"} +} + + +# cleanup () +# ---------- +# Remove what should be removed according to options. +# Called at the end of each compilation cycle, and at the end of +# the script. Changes the current directory. +cleanup () +{ + case $build_mode in + local) cd_orig; remove "$t2ddir";; + clean) mostly_clean;; + tidy) ;; + esac +} + + + +## ---------------------- ## +## Command line parsing. ## +## ---------------------- ## + +# Push a token among the arguments that will be used to notice when we +# ended options/arguments parsing. +# Use "set dummy ...; shift" rather than 'set - ..." because on +# Solaris set - turns off set -x (but keeps set -e). +# Use ${1+"$@"} rather than "$@" because Digital Unix and Ultrix 4.3 +# still expand "$@" to a single argument (the empty string) rather +# than nothing at all. +arg_sep="$$--$$" +set dummy ${1+"$@"} "$arg_sep"; shift + +# +# Parse command line arguments. +while test x"$1" != x"$arg_sep"; do + + # Handle --option=value by splitting apart and putting back on argv. + case "$1" in + --*=*) + opt=`echo "$1" | sed -e 's/=.*//'` + val=`echo "$1" | sed -e 's/[^=]*=//'` + shift + set dummy "$opt" "$val" ${1+"$@"}; shift + ;; + esac + + # This recognizes --quark as --quiet. So what. + case "$1" in + -@ ) escape=@;; + # Silently and without documentation accept -b and --b[atch] as synonyms. + -b | --batch) batch=true;; + --build) shift; build_mode=$1;; + --build-dir) shift; build_dir=$1; build_mode=tidy;; + -c | --clean) build_mode=clean;; + -D | --debug) debug=true;; + --dvi) out_lang=dvi;; + --dvipdf) out_lang=dvipdf;; + -e | -E | --expand) expand=t;; + -h | --help) usage;; + --html) out_lang=html;; + -I) shift; list_concat_dirs includes "$1";; + --info) out_lang=info;; + -l | --lang | --language) shift; set_language=$1;; + --mostly-clean) action=mostly-clean;; + --no-line-error) no_line_error=true;; + -o | --out | --output) + shift + # Make it absolute, just in case we also have --clean, or whatever. + oname=`absolute "$1"`;; + -p | --pdf) out_lang=pdf;; + --ps) out_lang=ps;; + -q | -s | --quiet | --silent) quiet=true; batch=true;; + -r | --recode) recode=true;; + --recode-from) shift; recode=true; recode_from="$1";; + --src-specials) src_specials=--src-specials;; + -t | --texinfo | --command ) shift; textra="$textra\\ +"`echo "$1" | sed 's/\\\\/\\\\\\\\/g'`;; + --text) out_lang=text;; + --translate-file ) shift; translate_file="$1";; + --tidy) build_mode=tidy;; + -v | --vers*) version;; + -V | --verb*) verb=true;; + --) # What remains are not options. + shift + while test x"$1" != x"$arg_sep"; do + set dummy ${1+"$@"} "$1"; shift + shift + done + break;; + -*) + error 1 "Unknown or ambiguous option \`$1'." \ + "Try \`--help' for more information." + ;; + *) set dummy ${1+"$@"} "$1"; shift;; + esac + shift +done +# Pop the token +shift + +# $tidy: compile in a t2d directory. +# $clean: remove all the aux files. +case $build_mode in + local) clean=false; tidy=false;; + tidy) clean=false; tidy=true;; + clean) clean=true; tidy=true;; + *) error 1 "invalid build mode: $build_mode";; +esac + +# Interpret remaining command line args as filenames. +case $# in + 0) + error 2 "Missing file arguments." "Try \`--help' for more information." + ;; + 1) ;; + *) + if test -n "$oname"; then + error 2 "Can't use option \`--output' with more than one argument." + fi + ;; +esac + + +# We can't do much without tex. +# +if findprog ${TEX:-tex}; then :; else cat <<EOM +You don't have a working TeX binary (${TEX:-tex}) installed anywhere in +your PATH, and texi2dvi cannot proceed without one. If you want to use +this script, you'll need to install TeX (if you don't have it) or change +your PATH or TEX environment variable (if you do). See the --help +output for more details. + +For information about obtaining TeX, please see http://www.tug.org. If +you happen to be using Debian, you can get it with this command: + apt-get install tetex-bin +EOM + exit 1 +fi + + +# We want to use etex (or pdftex) if they are available, and the user +# didn't explicitly specify. We don't check for elatex and pdfelatex +# because (as of 2003), the LaTeX team has asked that new distributions +# use etex by default anyway. +# +# End up with the TEX and PDFTEX variables set to what we are going to use. +if test -z "$TEX"; then + if findprog etex; then TEX=etex; else TEX=tex; fi +fi +# +if test -z "$PDFTEX"; then + if findprog pdfetex; then PDFTEX=pdfetex; else PDFTEX=pdftex; fi +fi + + +# File descriptor usage: +# 0 standard input +# 1 standard output (--verbose messages) +# 2 standard error +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 tools output (turned off by --quiet) +# 6 tracing/debugging (set -x output, etc.) + + +# Main tools' output (TeX, etc.) that TeX users are used to seeing. +# +# If quiet, discard, else redirect to the message flow. +if $quiet; then + exec 5>/dev/null +else + exec 5>&1 +fi + + +# Enable tracing, and auxiliary tools output. +# +# Should be used where you'd typically use /dev/null to throw output +# away. But sometimes it is convenient to see that output (e.g., from +# a grep) to aid debugging. Especially debugging at distance, via the +# user. +if $debug; then + exec 6>&1 + set -x +else + exec 6>/dev/null +fi + +# + +# input_file_name_decode +# ---------------------- +# Decode COMMAND_LINE_FILENAME, and compute: +# - COMMAND_LINE_FILENAME clean of TeX commands +# - IN_DIR +# The directory to the input file, possibly absolute if needed. +# - IN_DIR_ABS +# The absolute directory of the input file. +# - IN_BASE +# The input file base name (no directory part). +# - IN_NOEXT +# The input file name without extensions (nor directory part). +# - IN_INPUT +# Defaults to COMMAND_LINE_FILENAME, but might change if the +# input is preprocessed (recode etc.). With directory, possibly absolute. +input_file_name_decode () +{ + # See if we are run from within AUC-Tex, in which case we are + # passed `\input{FOO.tex}' or even `\nonstopmode\input{FOO.tex}'. + case $command_line_filename in + *\\nonstopmode*) + batch=true;; + esac + case $command_line_filename in + *\\input{*}*) + # Let AUC-TeX error parser deal with line numbers. + line_error=false + command_line_filename=`\ + expr X"$command_line_filename" : X'.*input{\([^}]*\)}'` + ;; + esac + + # If the COMMAND_LINE_FILENAME is not absolute (e.g., --debug.tex), + # prepend `./' in order to avoid that the tools take it as an option. + echo "$command_line_filename" | $EGREP '^(/|[A-z]:/)' >&6 \ + || command_line_filename="./$command_line_filename" + + # See if the file exists. If it doesn't we're in trouble since, even + # though the user may be able to reenter a valid filename at the tex + # prompt (assuming they're attending the terminal), this script won't + # be able to find the right xref files and so forth. + test -r "$command_line_filename" || + error 1 "cannot read $command_line_filename, skipping." + + # Get the name of the current directory. + in_dir=`func_dirname "$command_line_filename"` + in_dir_abs=`absolute "$in_dir"` + # In a clean build, we `cd', so get an absolute file name. + if $tidy; then + in_dir=$in_dir_abs + fi + + # Strip directory part but leave extension. + in_base=`basename "$command_line_filename"` + # Strip extension. + in_noext=`echo "$in_base" | sed 's/\.[^.]*$//'` + + # The normalized file name to compile. Must always point to the + # file to actually compile (in case of recoding, macro-expansion etc.). + in_input=$in_dir/$in_base + + + # Compute the output file name. + if test x"$oname" != x; then + out_name=$oname + else + out_name=$in_noext.`out_lang_ext` + fi + out_dir=`func_dirname "$out_name"` + out_dir_abs=`absolute "$out_dir"` + out_base=`basename "$out_name"` + out_noext=`echo "$out_base" | sed 's/\.[^.]*$//'` +} + + +## -------------- ## +## TeXify files. ## +## -------------- ## + +for command_line_filename +do + verbose "Processing $command_line_filename ..." + + input_file_name_decode + + # `texinfo' or `latex'? + in_lang=`compute_language "$command_line_filename"` + + # An auxiliary directory used for all the auxiliary tasks involved + # in compiling this document. + case $build_dir in + '' | . ) t2ddir=$out_noext.t2d ;; + *) # Avoid collisions between multiple occurrences of the same + # file. The sed expression is fragile if the cwd has + # active characters. + t2ddir=$build_dir/`echo "$out_dir_abs/$out_noext.t2d" | + sed "s,^$orig_pwd/,," | + sed 's,/,!,g'` + esac + # Remove it at exit if clean mode. + trap "cleanup" 0 1 2 15 + + ensure_dir "$build_dir" "$t2ddir" + + # We will change directory, better work with an absolute path... + t2ddir=`absolute "$t2ddir"` + # Sometimes there are incompatibilities between auxiliary files for + # DVI and PDF. The contents can also change whether we work on PDF + # and/or DVI. So keep separate spaces for each. + workdir=$t2ddir/`out_lang_tex` + ensure_dir "$workdir" + + # _build. In a tidy build, where the auxiliary files are output. + if $tidy; then + work_build=$workdir/build + else + work_build=. + fi + + # _bak. Copies of the previous auxiliary files (another round is + # run if they differ from the new ones). + work_bak=$workdir/bak + + # Make those directories. + ensure_dir "$work_build" "$work_bak" + + case $action in + compile) + # Compile the document. + compile + cleanup + ;; + + mostly-clean) + mostly_clean + ;; + esac +done + +verbose "done." +exit 0 # exit successfully, not however we ended the loop. diff --git a/util/texi2dvi.test b/util/texi2dvi.test new file mode 100755 index 0000000..2f3f075 --- /dev/null +++ b/util/texi2dvi.test @@ -0,0 +1,84 @@ +#! /bin/sh +# Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Texinfo. +# +# GNU Texinfo 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. +# +# GNU Texinfo 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/>. + +required='tex' + +. ./defs || exit 1 + +set -e + +# one_run ARGS -- FILES +# --------------------- +# Run texi2dvi with ARGS, expect the FILES to be left. Remove them. +one_run () +{ + # Testing the local build mode. + # Use @foo to check that -t works properly. + echo "@foo" | create_input_texi + TEXI2DVI_pass $(optionset_get 1 "$@") \ + -t '@macro foo' \ + -t 'Foo' \ + -t '@end macro' \ + input.texi + # There should only be the expected FILES and the input file. + assert_and_remove_files $(optionset_get 2 "$@") input.texi +} + +one_run --batch \ + -- \ + input.aux input.cp input.dvi input.fn input.ky input.log \ + input.pg input.tp input.vr + + +one_run --batch -o output.dvi \ + -- \ + input.aux input.cp input.fn input.ky input.log \ + input.pg input.tp input.vr output.dvi + + +# Testing the clean build mode. +for mode in --clean --build=clean +do + # There should only be the DVI and the TEXI file. + one_run $mode --batch -- input.dvi + + # There should only be the DVI and the TEXI file. + one_run $mode --batch -o output.dvi -- output.dvi +done + + +# Testing the tidy build mode. +one_run --build=tidy --batch -o output.dvi \ + -- \ + output.dvi output.t2d + + +# mostly-clean should remove auxiliary files, but not the expected +# output. +touch output.dvi +one_run --build=tidy --batch -o output.dvi --mostly-clean \ + -- \ + output.dvi + + +# There should only be the DVI and the TEXI file. +create_input_texi </dev/null +cp input.texi input2.texi +one_run --clean --batch input.texi input2.texi \ + -- \ + input2.dvi input2.texi input.dvi diff --git a/util/texi2pdf b/util/texi2pdf new file mode 100755 index 0000000..a030a74 --- /dev/null +++ b/util/texi2pdf @@ -0,0 +1,19 @@ +#!/bin/sh +# $Id: texi2pdf,v 1.2 2005/01/28 01:52:04 karl Exp $ +# Written by Thomas Esser. Public domain. +# Execute texi2dvi --pdf. + +test -f /bin/ksh && test -z "$RUNNING_KSH" \ + && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \ + && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; } +unset RUNNING_KSH + +test -f /bin/bsh && test -z "$RUNNING_BSH" \ + && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \ + && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; } +unset RUNNING_BSH + +# hack around a bug in zsh: +test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"' + +texi2dvi --pdf ${1+"$@"} diff --git a/util/texindex.c b/util/texindex.c new file mode 100644 index 0000000..431f27e --- /dev/null +++ b/util/texindex.c @@ -0,0 +1,1194 @@ +/* texindex -- sort TeX index dribble output into an actual index. + $Id: texindex.c,v 1.24 2008/02/22 19:18:25 karl Exp $ + + Copyright (C) 1987, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "system.h" +#include <getopt.h> + +char *program_name = "texindex"; + +#if defined (emacs) +# include "../src/config.h" +/* Some s/os.h files redefine these. */ +# undef read +# undef close +# undef write +# undef open +#endif + +#if !defined (HAVE_MEMSET) +#undef memset +#define memset(ptr, ignore, count) bzero (ptr, count) +#endif + +#if !defined (SEEK_SET) +# define SEEK_SET 0 +# define SEEK_CUR 1 +# define SEEK_END 2 +#endif /* !SEEK_SET */ + +/* When sorting in core, this structure describes one line + and the position and length of its first keyfield. */ +struct lineinfo +{ + char *text; /* The actual text of the line. */ + union { + char *text; /* The start of the key (for textual comparison). */ + long number; /* The numeric value (for numeric comparison). */ + } key; + long keylen; /* Length of KEY field. */ +}; + +/* This structure describes a field to use as a sort key. */ +struct keyfield +{ + int startwords; /* Number of words to skip. */ + int startchars; /* Number of additional chars to skip. */ + int endwords; /* Number of words to ignore at end. */ + int endchars; /* Ditto for characters of last word. */ + char ignore_blanks; /* Non-zero means ignore spaces and tabs. */ + char fold_case; /* Non-zero means case doesn't matter. */ + char reverse; /* Non-zero means compare in reverse order. */ + char numeric; /* Non-zeros means field is ASCII numeric. */ + char positional; /* Sort according to file position. */ + char braced; /* Count balanced-braced groupings as fields. */ +}; + +/* Vector of keyfields to use. */ +struct keyfield keyfields[3]; + +/* Number of keyfields stored in that vector. */ +int num_keyfields = 3; + +/* Vector of input file names, terminated with a null pointer. */ +char **infiles; + +/* Vector of corresponding output file names, or NULL, meaning default it + (add an `s' to the end). */ +char **outfiles; + +/* Length of `infiles'. */ +int num_infiles; + +/* Pointer to the array of pointers to lines being sorted. */ +char **linearray; + +/* The allocated length of `linearray'. */ +long nlines; + +/* During in-core sort, this points to the base of the data block + which contains all the lines of data. */ +char *text_base; + +/* Initially 0; changed to 1 if we want initials in this index. */ +int need_initials; + +/* Remembers the first initial letter seen in this index, so we can + determine whether we need initials in the sorted form. */ +char first_initial; + +/* Forward declarations of functions in this file. */ +void decode_command (int argc, char **argv); +void sort_in_core (char *infile, int total, char *outfile); +char **parsefile (char *filename, char **nextline, char *data, long int size); +char *find_field (struct keyfield *keyfield, char *str, long int *lengthptr); +char *find_pos (char *str, int words, int chars, int ignore_blanks); +long find_value (char *start, long int length); +char *find_braced_pos (char *str, int words, int chars, int ignore_blanks); +char *find_braced_end (char *str); +void writelines (char **linearray, int nlines, FILE *ostream); +int compare_field (struct keyfield *keyfield, char *start1, + long int length1, long int pos1, char *start2, + long int length2, long int pos2); +int compare_full (const void *, const void *); +void pfatal_with_name (const char *name); +void fatal (const char *format, const char *arg); +void error (const char *format, const char *arg); +void *xmalloc (), *xrealloc (); +static char *concat3 (const char *, const char *, const char *); + +int +main (int argc, char *argv[]) +{ + int i; + +#ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +#endif + + /* Set the text message domain. */ + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + /* In case we write to a redirected stdout that fails. */ + /* not ready atexit (close_stdout); */ + + /* Describe the kind of sorting to do. */ + /* The first keyfield uses the first braced field and folds case. */ + keyfields[0].braced = 1; + keyfields[0].fold_case = 1; + keyfields[0].endwords = -1; + keyfields[0].endchars = -1; + + /* The second keyfield uses the second braced field, numerically. */ + keyfields[1].braced = 1; + keyfields[1].numeric = 1; + keyfields[1].startwords = 1; + keyfields[1].endwords = -1; + keyfields[1].endchars = -1; + + /* The third keyfield (which is ignored while discarding duplicates) + compares the whole line. */ + keyfields[2].endwords = -1; + keyfields[2].endchars = -1; + + decode_command (argc, argv); + + /* Process input files completely, one by one. */ + + for (i = 0; i < num_infiles; i++) + { + int desc; + off_t ptr; + char *outfile; + struct stat instat; + + desc = open (infiles[i], O_RDONLY, 0); + if (desc < 0) + pfatal_with_name (infiles[i]); + + if (stat (infiles[i], &instat)) + pfatal_with_name (infiles[i]); + if (S_ISDIR (instat.st_mode)) + { +#ifdef EISDIR + errno = EISDIR; +#endif + pfatal_with_name (infiles[i]); + } + + lseek (desc, (off_t) 0, SEEK_END); + ptr = (off_t) lseek (desc, (off_t) 0, SEEK_CUR); + + close (desc); + + outfile = outfiles[i]; + if (!outfile) + outfile = concat3 (infiles[i], "s", ""); + + need_initials = 0; + first_initial = '\0'; + + if (ptr != (int)ptr) + { + fprintf (stderr, "%s: %s: file too large\n", program_name, + infiles[i]); + xexit (1); + } + sort_in_core (infiles[i], (int)ptr, outfile); + } + + xexit (0); + return 0; /* Avoid bogus warnings. */ +} + +typedef struct +{ + char *long_name; + char *short_name; + int *variable_ref; + int variable_value; + char *arg_name; + char *doc_string; +} TEXINDEX_OPTION; + +TEXINDEX_OPTION texindex_options[] = { + { "--help", "-h", (int *)NULL, 0, (char *)NULL, + N_("display this help and exit") }, + { "--output", "-o", (int *)NULL, 0, "FILE", + N_("send output to FILE") }, + { "--version", (char *)NULL, (int *)NULL, 0, (char *)NULL, + N_("display version information and exit") }, + { (char *)NULL, (char *)NULL, (int *)NULL, 0, (char *)NULL } +}; + +void +usage (int result_value) +{ + register int i; + FILE *f = result_value ? stderr : stdout; + + fprintf (f, _("Usage: %s [OPTION]... FILE...\n"), program_name); + fprintf (f, _("Generate a sorted index for each TeX output FILE.\n")); + /* Avoid trigraph nonsense. */ + fprintf (f, +_("Usually FILE... is specified as `foo.%c%c\' for a document `foo.texi'.\n"), + '?', '?'); /* avoid trigraph in cat-id-tbl.c */ + fprintf (f, _("\nOptions:\n")); + + for (i = 0; texindex_options[i].long_name; i++) + { + putc (' ', f); + + if (texindex_options[i].short_name) + fprintf (f, "%s, ", texindex_options[i].short_name); + + fprintf (f, "%s %s", + texindex_options[i].long_name, + texindex_options[i].arg_name + ? texindex_options[i].arg_name : ""); + + fprintf (f, "\t%s\n", _(texindex_options[i].doc_string)); + } + fputs (_("\n\ +Email bug reports to bug-texinfo@gnu.org,\n\ +general questions and discussion to help-texinfo@gnu.org.\n\ +Texinfo home page: http://www.gnu.org/software/texinfo/"), f); + fputs ("\n", f); + + xexit (result_value); +} + +/* Decode the command line arguments to set the parameter variables + and set up the vector of keyfields and the vector of input files. */ + +void +decode_command (int argc, char **argv) +{ + int arg_index = 1; + char **ip; + char **op; + + /* Allocate ARGC input files, which must be enough. */ + + infiles = (char **) xmalloc (argc * sizeof (char *)); + outfiles = (char **) xmalloc (argc * sizeof (char *)); + ip = infiles; + op = outfiles; + + while (arg_index < argc) + { + char *arg = argv[arg_index++]; + + if (*arg == '-') + { + if (strcmp (arg, "--version") == 0) + { + printf ("texindex (GNU %s) %s\n", PACKAGE, VERSION); + puts (""); + printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ +License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\ +This is free software: you are free to change and redistribute it.\n\ +There is NO WARRANTY, to the extent permitted by law.\n"), + "2008"); + xexit (0); + } + else if ((strcmp (arg, "--keep") == 0) || + (strcmp (arg, "-k") == 0)) + { + /* Ignore, for backward compatibility */ + } + else if ((strcmp (arg, "--help") == 0) || + (strcmp (arg, "-h") == 0)) + { + usage (0); + } + else if ((strcmp (arg, "--output") == 0) || + (strcmp (arg, "-o") == 0)) + { + if (argv[arg_index] != (char *)NULL) + { + arg_index++; + if (op > outfiles) + *(op - 1) = argv[arg_index]; + } + else + usage (1); + } + else + usage (1); + } + else + { + *ip++ = arg; + *op++ = (char *)NULL; + } + } + + /* Record number of keyfields and terminate list of filenames. */ + num_infiles = ip - infiles; + *ip = (char *)NULL; + if (num_infiles == 0) + usage (1); +} + +/* Compare LINE1 and LINE2 according to the specified set of keyfields. */ + +int +compare_full (const void *p1, const void *p2) +{ + char **line1 = (char **) p1; + char **line2 = (char **) p2; + int i; + + /* Compare using the first keyfield; + if that does not distinguish the lines, try the second keyfield; + and so on. */ + + for (i = 0; i < num_keyfields; i++) + { + long length1, length2; + char *start1 = find_field (&keyfields[i], *line1, &length1); + char *start2 = find_field (&keyfields[i], *line2, &length2); + int tem = compare_field (&keyfields[i], start1, length1, + *line1 - text_base, + start2, length2, *line2 - text_base); + if (tem) + { + if (keyfields[i].reverse) + return -tem; + return tem; + } + } + + return 0; /* Lines match exactly. */ +} + +/* Compare LINE1 and LINE2, described by structures + in which the first keyfield is identified in advance. + For positional sorting, assumes that the order of the lines in core + reflects their nominal order. */ +int +compare_prepared (const void *p1, const void *p2) +{ + struct lineinfo *line1 = (struct lineinfo *) p1; + struct lineinfo *line2 = (struct lineinfo *) p2; + int i; + int tem; + char *text1, *text2; + + /* Compare using the first keyfield, which has been found for us already. */ + if (keyfields->positional) + { + if (line1->text - text_base > line2->text - text_base) + tem = 1; + else + tem = -1; + } + else if (keyfields->numeric) + tem = line1->key.number - line2->key.number; + else + tem = compare_field (keyfields, line1->key.text, line1->keylen, 0, + line2->key.text, line2->keylen, 0); + if (tem) + { + if (keyfields->reverse) + return -tem; + return tem; + } + + text1 = line1->text; + text2 = line2->text; + + /* Compare using the second keyfield; + if that does not distinguish the lines, try the third keyfield; + and so on. */ + + for (i = 1; i < num_keyfields; i++) + { + long length1, length2; + char *start1 = find_field (&keyfields[i], text1, &length1); + char *start2 = find_field (&keyfields[i], text2, &length2); + int tem = compare_field (&keyfields[i], start1, length1, + text1 - text_base, + start2, length2, text2 - text_base); + if (tem) + { + if (keyfields[i].reverse) + return -tem; + return tem; + } + } + + return 0; /* Lines match exactly. */ +} + +/* Like compare_full but more general. + You can pass any strings, and you can say how many keyfields to use. + POS1 and POS2 should indicate the nominal positional ordering of + the two lines in the input. */ + +int +compare_general (char *str1, char *str2, long int pos1, long int pos2, int use_keyfields) +{ + int i; + + /* Compare using the first keyfield; + if that does not distinguish the lines, try the second keyfield; + and so on. */ + + for (i = 0; i < use_keyfields; i++) + { + long length1, length2; + char *start1 = find_field (&keyfields[i], str1, &length1); + char *start2 = find_field (&keyfields[i], str2, &length2); + int tem = compare_field (&keyfields[i], start1, length1, pos1, + start2, length2, pos2); + if (tem) + { + if (keyfields[i].reverse) + return -tem; + return tem; + } + } + + return 0; /* Lines match exactly. */ +} + +/* Find the start and length of a field in STR according to KEYFIELD. + A pointer to the starting character is returned, and the length + is stored into the int that LENGTHPTR points to. */ + +char * +find_field (struct keyfield *keyfield, char *str, long int *lengthptr) +{ + char *start; + char *end; + char *(*fun) (); + + if (keyfield->braced) + fun = find_braced_pos; + else + fun = find_pos; + + start = (*fun) (str, keyfield->startwords, keyfield->startchars, + keyfield->ignore_blanks); + if (keyfield->endwords < 0) + { + if (keyfield->braced) + end = find_braced_end (start); + else + { + end = start; + while (*end && *end != '\n') + end++; + } + } + else + { + end = (*fun) (str, keyfield->endwords, keyfield->endchars, 0); + if (end - str < start - str) + end = start; + } + *lengthptr = end - start; + return start; +} + +/* Return a pointer to a specified place within STR, + skipping (from the beginning) WORDS words and then CHARS chars. + If IGNORE_BLANKS is nonzero, we skip all blanks + after finding the specified word. */ + +char * +find_pos (char *str, int words, int chars, int ignore_blanks) +{ + int i; + char *p = str; + + for (i = 0; i < words; i++) + { + char c; + /* Find next bunch of nonblanks and skip them. */ + while ((c = *p) == ' ' || c == '\t') + p++; + while ((c = *p) && c != '\n' && !(c == ' ' || c == '\t')) + p++; + if (!*p || *p == '\n') + return p; + } + + while (*p == ' ' || *p == '\t') + p++; + + for (i = 0; i < chars; i++) + { + if (!*p || *p == '\n') + break; + p++; + } + return p; +} + +/* Like find_pos but assumes that each field is surrounded by braces + and that braces within fields are balanced. */ + +char * +find_braced_pos (char *str, int words, int chars, int ignore_blanks) +{ + int i; + int bracelevel; + char *p = str; + char c; + + for (i = 0; i < words; i++) + { + bracelevel = 1; + while ((c = *p++) != '{' && c != '\n' && c) + /* Do nothing. */ ; + if (c != '{') + return p - 1; + while (bracelevel) + { + c = *p++; + if (c == '{') + bracelevel++; + if (c == '}') + bracelevel--; + if (c == 0 || c == '\n') + return p - 1; + } + } + + while ((c = *p++) != '{' && c != '\n' && c) + /* Do nothing. */ ; + + if (c != '{') + return p - 1; + + if (ignore_blanks) + while ((c = *p) == ' ' || c == '\t') + p++; + + for (i = 0; i < chars; i++) + { + if (!*p || *p == '\n') + break; + p++; + } + return p; +} + +/* Find the end of the balanced-brace field which starts at STR. + The position returned is just before the closing brace. */ + +char * +find_braced_end (char *str) +{ + int bracelevel; + char *p = str; + char c; + + bracelevel = 1; + while (bracelevel) + { + c = *p++; + if (c == '{') + bracelevel++; + if (c == '}') + bracelevel--; + if (c == 0 || c == '\n') + return p - 1; + } + return p - 1; +} + +long +find_value (char *start, long int length) +{ + while (length != 0L) + { + if (isdigit (*start)) + return atol (start); + length--; + start++; + } + return 0l; +} + +/* Vector used to translate characters for comparison. + This is how we make all alphanumerics follow all else, + and ignore case in the first sorting. */ +int char_order[256]; + +void +init_char_order (void) +{ + int i; + for (i = 1; i < 256; i++) + char_order[i] = i; + + for (i = '0'; i <= '9'; i++) + char_order[i] += 512; + + for (i = 'a'; i <= 'z'; i++) + { + char_order[i] = 512 + i; + char_order[i + 'A' - 'a'] = 512 + i; + } +} + +/* Compare two fields (each specified as a start pointer and a character count) + according to KEYFIELD. + The sign of the value reports the relation between the fields. */ + +int +compare_field (struct keyfield *keyfield, char *start1, long int length1, + long int pos1, char *start2, long int length2, long int pos2) +{ + if (keyfields->positional) + { + if (pos1 > pos2) + return 1; + else + return -1; + } + if (keyfield->numeric) + { + long value = find_value (start1, length1) - find_value (start2, length2); + if (value > 0) + return 1; + if (value < 0) + return -1; + return 0; + } + else + { + char *p1 = start1; + char *p2 = start2; + char *e1 = start1 + length1; + char *e2 = start2 + length2; + + while (1) + { + int c1, c2; + + if (p1 == e1) + c1 = 0; + else + c1 = *p1++; + if (p2 == e2) + c2 = 0; + else + c2 = *p2++; + + if (char_order[c1] != char_order[c2]) + return char_order[c1] - char_order[c2]; + if (!c1) + break; + } + + /* Strings are equal except possibly for case. */ + p1 = start1; + p2 = start2; + while (1) + { + int c1, c2; + + if (p1 == e1) + c1 = 0; + else + c1 = *p1++; + if (p2 == e2) + c2 = 0; + else + c2 = *p2++; + + if (c1 != c2) + /* Reverse sign here so upper case comes out last. */ + return c2 - c1; + if (!c1) + break; + } + + return 0; + } +} + +/* Sort INFILE, whose size is TOTAL, + assuming that is small enough to be done in-core, + then indexify it and send the output to OUTFILE (or to stdout). */ + +void +sort_in_core (char *infile, int total, char *outfile) +{ + char **nextline; + char *data = (char *) xmalloc (total + 1); + char *file_data; + long file_size; + int i; + FILE *ostream = stdout; + struct lineinfo *lineinfo; + + /* Read the contents of the file into the moby array `data'. */ + + int desc = open (infile, O_RDONLY, 0); + + if (desc < 0) + fatal (_("failure reopening %s"), infile); + for (file_size = 0;;) + { + i = read (desc, data + file_size, total - file_size); + if (i <= 0) + break; + file_size += i; + } + file_data = data; + data[file_size] = 0; + + close (desc); + + if (file_size > 0 && data[0] != '\\' && data[0] != '@') + { + error (_("%s: not a texinfo index file"), infile); + return; + } + + init_char_order (); + + /* Sort routines want to know this address. */ + + text_base = data; + + /* Create the array of pointers to lines, with a default size + frequently enough. */ + + nlines = total / 50; + if (!nlines) + nlines = 2; + linearray = (char **) xmalloc (nlines * sizeof (char *)); + + /* `nextline' points to the next free slot in this array. + `nlines' is the allocated size. */ + + nextline = linearray; + + /* Parse the input file's data, and make entries for the lines. */ + + nextline = parsefile (infile, nextline, file_data, file_size); + if (nextline == 0) + { + error (_("%s: not a texinfo index file"), infile); + return; + } + + /* Sort the lines. */ + + /* If we have enough space, find the first keyfield of each line in advance. + Make a `struct lineinfo' for each line, which records the keyfield + as well as the line, and sort them. */ + + lineinfo = malloc ((nextline - linearray) * sizeof (struct lineinfo)); + + if (lineinfo) + { + struct lineinfo *lp; + char **p; + + for (lp = lineinfo, p = linearray; p != nextline; lp++, p++) + { + lp->text = *p; + lp->key.text = find_field (keyfields, *p, &lp->keylen); + if (keyfields->numeric) + lp->key.number = find_value (lp->key.text, lp->keylen); + } + + qsort (lineinfo, nextline - linearray, sizeof (struct lineinfo), + compare_prepared); + + for (lp = lineinfo, p = linearray; p != nextline; lp++, p++) + *p = lp->text; + + free (lineinfo); + } + else + qsort (linearray, nextline - linearray, sizeof (char *), compare_full); + + /* Open the output file. */ + + if (outfile) + { + ostream = fopen (outfile, "w"); + if (!ostream) + pfatal_with_name (outfile); + } + + writelines (linearray, nextline - linearray, ostream); + if (outfile) + fclose (ostream); + + free (linearray); + free (data); +} + +/* Parse an input string in core into lines. + DATA is the input string, and SIZE is its length. + Data goes in LINEARRAY starting at NEXTLINE. + The value returned is the first entry in LINEARRAY still unused. + Value 0 means input file contents are invalid. */ + +char ** +parsefile (char *filename, char **nextline, char *data, long int size) +{ + char *p, *end; + char **line = nextline; + + p = data; + end = p + size; + *end = 0; + + while (p != end) + { + if (p[0] != '\\' && p[0] != '@') + return 0; + + *line = p; + + /* Find the first letter of the first field of this line. If it + is different from the first letter of the first field of the + first line, we need initial headers in the output index. */ + while (*p && *p != '{') + p++; + if (p == end) + return 0; + p++; + if (first_initial) + { + if (first_initial != toupper (*p)) + need_initials = 1; + } + else + first_initial = toupper (*p); + + while (*p && *p != '\n') + p++; + if (p != end) + p++; + + line++; + if (line == linearray + nlines) + { + char **old = linearray; + linearray = xrealloc (linearray, sizeof (char *) * (nlines *= 4)); + line += linearray - old; + } + } + + return line; +} + +/* Indexification is a filter applied to the sorted lines + as they are being written to the output file. + Multiple entries for the same name, with different page numbers, + get combined into a single entry with multiple page numbers. + The first braced field, which is used for sorting, is discarded. + However, its first character is examined, folded to lower case, + and if it is different from that in the previous line fed to us + a \initial line is written with one argument, the new initial. + + If an entry has four braced fields, then the second and third + constitute primary and secondary names. + In this case, each change of primary name + generates a \primary line which contains only the primary name, + and in between these are \secondary lines which contain + just a secondary name and page numbers. */ + +/* The last primary name we wrote a \primary entry for. + If only one level of indexing is being done, this is the last name seen. */ +char *lastprimary; +/* Length of storage allocated for lastprimary. */ +int lastprimarylength; + +/* Similar, for the secondary name. */ +char *lastsecondary; +int lastsecondarylength; + +/* Zero if we are not in the middle of writing an entry. + One if we have written the beginning of an entry but have not + yet written any page numbers into it. + Greater than one if we have written the beginning of an entry + plus at least one page number. */ +int pending; + +/* The initial (for sorting purposes) of the last primary entry written. + When this changes, a \initial {c} line is written */ + +char *lastinitial; + +int lastinitiallength; + +/* When we need a string of length 1 for the value of lastinitial, + store it here. */ + +char lastinitial1[2]; + +/* Initialize static storage for writing an index. */ + +void +init_index (void) +{ + pending = 0; + lastinitial = lastinitial1; + lastinitial1[0] = 0; + lastinitial1[1] = 0; + lastinitiallength = 0; + lastprimarylength = 100; + lastprimary = (char *) xmalloc (lastprimarylength + 1); + memset (lastprimary, '\0', lastprimarylength + 1); + lastsecondarylength = 100; + lastsecondary = (char *) xmalloc (lastsecondarylength + 1); + memset (lastsecondary, '\0', lastsecondarylength + 1); +} + +/* Indexify. Merge entries for the same name, + insert headers for each initial character, etc. */ + +void +indexify (char *line, FILE *ostream) +{ + char *primary, *secondary, *pagenumber; + int primarylength, secondarylength = 0, pagelength; + int nosecondary; + int initiallength; + char *initial; + char initial1[2]; + register char *p; + + /* First, analyze the parts of the entry fed to us this time. */ + + p = find_braced_pos (line, 0, 0, 0); + if (*p == '{') + { + initial = p; + /* Get length of inner pair of braces starting at `p', + including that inner pair of braces. */ + initiallength = find_braced_end (p + 1) + 1 - p; + } + else + { + initial = initial1; + initial1[0] = toupper (*p); + initial1[1] = 0; + initiallength = 1; + } + + pagenumber = find_braced_pos (line, 1, 0, 0); + pagelength = find_braced_end (pagenumber) - pagenumber; + if (pagelength == 0) + fatal (_("No page number in %s"), line); + + primary = find_braced_pos (line, 2, 0, 0); + primarylength = find_braced_end (primary) - primary; + + secondary = find_braced_pos (line, 3, 0, 0); + nosecondary = !*secondary; + if (!nosecondary) + secondarylength = find_braced_end (secondary) - secondary; + + /* If the primary is different from before, make a new primary entry. */ + if (strncmp (primary, lastprimary, primarylength)) + { + /* Close off current secondary entry first, if one is open. */ + if (pending) + { + fputs ("}\n", ostream); + pending = 0; + } + + /* If this primary has a different initial, include an entry for + the initial. */ + if (need_initials && + (initiallength != lastinitiallength || + strncmp (initial, lastinitial, initiallength))) + { + fprintf (ostream, "\\initial {"); + fwrite (initial, 1, initiallength, ostream); + fputs ("}\n", ostream); + if (initial == initial1) + { + lastinitial = lastinitial1; + *lastinitial1 = *initial1; + } + else + { + lastinitial = initial; + } + lastinitiallength = initiallength; + } + + /* Make the entry for the primary. */ + if (nosecondary) + fputs ("\\entry {", ostream); + else + fputs ("\\primary {", ostream); + fwrite (primary, primarylength, 1, ostream); + if (nosecondary) + { + fputs ("}{", ostream); + pending = 1; + } + else + fputs ("}\n", ostream); + + /* Record name of most recent primary. */ + if (lastprimarylength < primarylength) + { + lastprimarylength = primarylength + 100; + lastprimary = (char *) xrealloc (lastprimary, + 1 + lastprimarylength); + } + strncpy (lastprimary, primary, primarylength); + lastprimary[primarylength] = 0; + + /* There is no current secondary within this primary, now. */ + lastsecondary[0] = 0; + } + + /* Should not have an entry with no subtopic following one with a + subtopic. */ + + if (nosecondary && *lastsecondary) + error (_("entry %s follows an entry with a secondary name"), line); + + /* Start a new secondary entry if necessary. */ + if (!nosecondary && strncmp (secondary, lastsecondary, secondarylength)) + { + if (pending) + { + fputs ("}\n", ostream); + pending = 0; + } + + /* Write the entry for the secondary. */ + fputs ("\\secondary {", ostream); + fwrite (secondary, secondarylength, 1, ostream); + fputs ("}{", ostream); + pending = 1; + + /* Record name of most recent secondary. */ + if (lastsecondarylength < secondarylength) + { + lastsecondarylength = secondarylength + 100; + lastsecondary = (char *) xrealloc (lastsecondary, + 1 + lastsecondarylength); + } + strncpy (lastsecondary, secondary, secondarylength); + lastsecondary[secondarylength] = 0; + } + + /* Here to add one more page number to the current entry. */ + if (pending++ != 1) + fputs (", ", ostream); /* Punctuate first, if this is not the first. */ + fwrite (pagenumber, pagelength, 1, ostream); +} + +/* Close out any unfinished output entry. */ + +void +finish_index (FILE *ostream) +{ + if (pending) + fputs ("}\n", ostream); + free (lastprimary); + free (lastsecondary); +} + +/* Copy the lines in the sorted order. + Each line is copied out of the input file it was found in. */ + +void +writelines (char **linearray, int nlines, FILE *ostream) +{ + char **stop_line = linearray + nlines; + char **next_line; + + init_index (); + + /* Output the text of the lines, and free the buffer space. */ + + for (next_line = linearray; next_line != stop_line; next_line++) + { + /* Output the line only if distinct from previous one. */ + if (next_line == linearray + /* Compare previous line with this one, using only the + explicitly specd keyfields. */ + || compare_general (*(next_line - 1), *next_line, 0L, 0L, + num_keyfields - 1)) + { + char *p = *next_line; + char c; + + while ((c = *p++) && c != '\n') + /* Do nothing. */ ; + *(p - 1) = 0; + indexify (*next_line, ostream); + } + } + + finish_index (ostream); +} + +/* Print error message and exit. */ + +void +fatal (const char *format, const char *arg) +{ + error (format, arg); + xexit (1); +} + +/* Print error message. FORMAT is printf control string, ARG is arg for it. */ +void +error (const char *format, const char *arg) +{ + printf ("%s: ", program_name); + printf (format, arg); + if (format[strlen (format) -1] != '\n') + printf ("\n"); +} + +void +perror_with_name (const char *name) +{ + fprintf (stderr, "%s: ", program_name); + perror (name); +} + +void +pfatal_with_name (const char *name) +{ + perror_with_name (name); + xexit (1); +} + + +/* Return a newly-allocated string concatenating S1, S2, and S3. */ + +static char * +concat3 (const char *s1, const char *s2, const char *s3) +{ + int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); + char *result = (char *) xmalloc (len1 + len2 + len3 + 1); + + strcpy (result, s1); + strcpy (result + len1, s2); + strcpy (result + len1 + len2, s3); + *(result + len1 + len2 + len3) = 0; + + return result; +} diff --git a/util/texinfo-cat.in b/util/texinfo-cat.in new file mode 100644 index 0000000..f0f0674 --- /dev/null +++ b/util/texinfo-cat.in @@ -0,0 +1,3 @@ +OVERRIDE YES + +PUBLIC "-//GNU//DTD TexinfoML V__VERSION__//EN" "texinfo.dtd" diff --git a/util/texinfo.dtd b/util/texinfo.dtd new file mode 100644 index 0000000..d07fdf6 --- /dev/null +++ b/util/texinfo.dtd @@ -0,0 +1,507 @@ +<!-- $Id: texinfo.dtd,v 1.13 2008/01/31 18:33:27 karl Exp $ + Document Type Definition for Texinfo XML output (the '-'-xml option). + + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. + + Author: Philippe Martin + Contributors: + Karl Eichwalder + Alper Ersoy + Karl Berry + Torsten Bronger +--> + +<!-- * ENTITIES * --> + +<!-- Meta-information --> +<!ENTITY % metainformation "setfilename | settitle | dircategory + | documentdescription"> +<!ENTITY % variables "setvalue | clearvalue"> + +<!-- Document language --> +<!ENTITY % lang "documentlanguage"> + +<!-- Language codes --> +<!ENTITY % languagecodes "aa|ab|af|am|ar|as|ay|az|ba|be|bg|bh|bi|bn|bo|br|ca|co|cs|cy|da|de|dz|el|en|eo|es|et|eu|fa|fi|fj|fo|fr|fy|ga|gd|gl|gn|gu|ha|he|hi|hr|hu|hy|ia|id|ie|ik|is|it|iu|ja|jw|ka|kk|kl|km|kn|ko|ks|ku|ky|la|ln|lo|lt|lv|mg|mi|mk|ml|mn|mo|mr|ms|mt|my|na|ne|nl|no|oc|om|or|pa|pl|ps|pt|qu|rm|rn|ro|ru|rw|sa|sd|sg|sh|si|sk|sl|sm|sn|so|sq|sr|ss|st|su|sv|sw|ta|te|tg|th|ti|tk|tl|tn|to|tr|ts|tt|tw|ug|uk|ur|uz|vi|vo|wo|xh|yi|yo|za|zh|zu"> + +<!-- ToC --> +<!ENTITY % toc "contents | shortcontents"> + +<!-- Title page --> +<!ENTITY % titlepage_cmds "author | booktitle | booksubtitle"> + +<!-- block --> +<!ENTITY % block "menu | para | quotation | example | smallexample | lisp + | smalllisp | cartouche | copying + | format | smallformat | display + | smalldisplay | itemize | enumerate | sp | center | group + | table | multitable | definition | float | image"> + +<!-- API definitions --> +<!ENTITY % definition.cmds "defcategory | deffunction | defvariable | defparam + | defdelimiter | deftype | defparamtype | defdatatype + | defclass | defclassvar | defoperation"> + +<!-- Headings --> +<!ENTITY % headings "majorheading | chapheading | heading | subheading + | subsubheading"> + + +<!-- Sectioning --> +<!ENTITY % section.level1 "top | chapter | unnumbered | appendix"> + +<!ENTITY % section.level2 "section | unnumberedsec | appendixsec"> + +<!ENTITY % section.level3 "subsection | unnumberedsubsec | appendixsubsec"> + +<!ENTITY % section.level4 "subsubsection | unnumberedsubsubsec + | appendixsubsubsec"> + +<!ENTITY % section.all "%section.level1; | %section.level2; | %section.level3; + | %section.level4;"> + + +<!ENTITY % section.level1.content "(%block; + | %section.level2; + | %section.level3; + | %section.level4; + | verbatim | titlepage | %toc; + | %lang; | %variables; + | %headings; + | listoffloats + | printindex)*"> + +<!ENTITY % section.level2.content "(%block; + | %section.level3; + | %section.level4; + | verbatim | titlepage | %toc; + | %lang; | %variables; + | %headings;)*"> + +<!ENTITY % section.level3.content "(%block; + | %section.level4; + | verbatim | titlepage | %toc; + | %lang; | %variables; + | %headings;)*"> + +<!ENTITY % section.level4.content "(%block; + | verbatim | titlepage | %toc; + | %lang; | %variables; + | %headings;)*"> + +<!-- Options (many missing) --> +<!ENTITY % onoff "on|off"> +<!ENTITY % option.cmds "frenchspacing"> + +<!-- Inline --> +<!ENTITY % Inline.emphasize "strong | emph"> +<!ENTITY % Inline.fonts "b | i | r | sansserif | slanted | titlefont | tt + | sc"> +<!ENTITY % Inline.footnote "footnote"> +<!ENTITY % Inline.markup "code | command | env | file | option | samp | verb + | dfn | cite | key | kbd | var | acronym | url"> +<!ENTITY % Inline.math "math | dmn"> +<!ENTITY % Inline.reference "xref | inforef | indexterm | email | uref"> +<!ENTITY % Inline.misc "click | clicksequence | logo | punct"> + +<!ENTITY % Inline.phrase + "%Inline.emphasize; | %Inline.misc; | %Inline.fonts; + | %Inline.markup; | %Inline.math; | %Inline.reference; + | %Inline.footnote; | %option.cmds; "> + + +<!-- * ELEMENTS * --> + +<!-- TOP Level Element --> +<!ELEMENT texinfo ((%metainformation; | titlepage | node | synindex | %block; | %toc; + | %variables; | %lang;)* )> +<!ATTLIST texinfo xml:lang (%languagecodes;) 'en'> + +<!-- meta-information --> +<!ELEMENT setfilename (#PCDATA)> +<!ELEMENT settitle (#PCDATA | %Inline.phrase;)*> +<!ELEMENT dircategory (#PCDATA)> + +<!ELEMENT setvalue (#PCDATA | %Inline.phrase;)*> +<!ELEMENT clearvalue EMPTY> +<!ATTLIST setvalue + name CDATA #REQUIRED> +<!ATTLIST clearvalue + name CDATA #REQUIRED> + +<!-- ToC --> +<!ELEMENT contents EMPTY> +<!ELEMENT shortcontents EMPTY> + +<!-- Document language --> +<!ELEMENT documentlanguage EMPTY> +<!ATTLIST documentlanguage xml:lang (%languagecodes;) 'en'> + +<!-- Titlepage --> +<!ELEMENT titlepage (%titlepage_cmds; | %block;)*> +<!ELEMENT author (#PCDATA | %Inline.phrase;)*> +<!ELEMENT booktitle (#PCDATA | %Inline.phrase;)*> +<!ELEMENT booksubtitle (#PCDATA | %Inline.phrase;)*> + +<!-- NODES --> +<!ELEMENT node (nodename, nodenext?, nodeprev?, nodeup?, + (%section.all; | %block; | %toc; | %lang;)*) > + +<!ELEMENT nodename (#PCDATA)> +<!ELEMENT nodenext (#PCDATA)> +<!ELEMENT nodeprev (#PCDATA)> +<!ELEMENT nodeup (#PCDATA)> + + +<!-- SECTIONING --> +<!ELEMENT top (title?, (%section.level1.content;))> + +<!ELEMENT chapter (title?, (%section.level1.content;))> +<!ELEMENT section (title?, (%section.level2.content;))> +<!ELEMENT subsection (title?, (%section.level3.content;))> +<!ELEMENT subsubsection (title?, (%section.level4.content;))> + +<!ELEMENT unnumbered (title?, (%section.level1.content;))> +<!ELEMENT unnumberedsec (title?, (%section.level2.content;))> +<!ELEMENT unnumberedsubsec (title?, (%section.level3.content;))> +<!ELEMENT unnumberedsubsubsec (title?, (%section.level4.content;))> + +<!ELEMENT appendix (title?, (%section.level1.content;))> +<!ELEMENT appendixsec (title?, (%section.level2.content;))> +<!ELEMENT appendixsubsec (title?, (%section.level3.content;))> +<!ELEMENT appendixsubsubsec (title?, (%section.level4.content;))> + +<!-- Headings and titles --> +<!ELEMENT majorheading (#PCDATA | %Inline.phrase;)*> +<!ELEMENT chapheading (#PCDATA | %Inline.phrase;)*> +<!ELEMENT heading (#PCDATA | %Inline.phrase;)*> +<!ELEMENT subheading (#PCDATA | %Inline.phrase;)*> +<!ELEMENT subsubheading (#PCDATA | %Inline.phrase;)*> +<!ELEMENT title (#PCDATA | %Inline.phrase;)*> + +<!-- Negative Indentation in Blocks --> +<!ELEMENT exdent (#PCDATA | %Inline.phrase;)*> + + +<!-- BLOCK Elements --> + +<!ELEMENT quotation (%block; | %Inline.phrase; | exdent)*> +<!ELEMENT documentdescription (#PCDATA | %block; | %Inline.phrase;)*> +<!ELEMENT example (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT smallexample (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT lisp (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT smalllisp (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT cartouche (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT copying (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT format (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT smallformat (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT display (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT smalldisplay (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT center (#PCDATA | %block; | %Inline.phrase; | exdent)*> +<!ELEMENT group (#PCDATA | %block; | %Inline.phrase; | exdent)*> + +<!ELEMENT image (alttext)> +<!ELEMENT alttext (#PCDATA)> +<!ATTLIST image + name CDATA #REQUIRED + extension CDATA #REQUIRED + width CDATA #REQUIRED + height CDATA #REQUIRED> + +<!-- Whitespace in these elements are always preserved --> +<!ATTLIST example xml:space (preserve) #FIXED 'preserve'> +<!ATTLIST smallexample xml:space (preserve) #FIXED 'preserve'> +<!ATTLIST lisp xml:space (preserve) #FIXED 'preserve'> +<!ATTLIST smalllisp xml:space (preserve) #FIXED 'preserve'> +<!ATTLIST display xml:space (preserve) #FIXED 'preserve'> +<!ATTLIST smalldisplay xml:space (preserve) #FIXED 'preserve'> +<!ATTLIST format xml:space (preserve) #FIXED 'preserve'> +<!ATTLIST smallformat xml:space (preserve) #FIXED 'preserve'> + +<!ELEMENT verbatim (#PCDATA)> +<!ATTLIST verbatim xml:space (preserve) #FIXED 'preserve'> + +<!ELEMENT para (#PCDATA | %Inline.phrase; | %lang;)*> +<!ATTLIST para + role CDATA #IMPLIED> + +<!ELEMENT menu (menuentry | detailmenu | para)*> +<!ELEMENT detailmenu (menuentry | para)*> +<!ELEMENT menuentry (menunode?, menutitle?, menucomment?)> +<!ELEMENT menunode (#PCDATA)> +<!ELEMENT menutitle (#PCDATA)> +<!ELEMENT menucomment (#PCDATA | %Inline.phrase;)*> + +<!-- Floating displays --> +<!ELEMENT float (floattype, floatpos, (%block;)*, + ((caption, shortcaption?) | (shortcaption, caption))?)> +<!ATTLIST float + name CDATA #IMPLIED> +<!ELEMENT floattype (#PCDATA)> +<!ELEMENT floatpos (#PCDATA)> +<!ELEMENT caption (#PCDATA | %Inline.phrase;)*> +<!ELEMENT shortcaption (#PCDATA | %Inline.phrase;)*> +<!ELEMENT listoffloats EMPTY> +<!ATTLIST listoffloats + type CDATA #IMPLIED> + +<!-- Lists --> +<!ELEMENT itemize (itemfunction, (item | itemize | enumerate | indexterm)*)> +<!ELEMENT enumerate (item | itemize | enumerate | indexterm)*> +<!ATTLIST enumerate + first CDATA #IMPLIED> + +<!ELEMENT item (%block;)*> + +<!ELEMENT itemfunction (#PCDATA | %Inline.phrase;)*> + +<!-- Tables --> +<!ELEMENT table (tableitem | indexterm)+> +<!ELEMENT tableitem ((tableterm, indexterm*)+, item?)> +<!ELEMENT tableterm (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT multitable (columnfraction*, thead?, tbody)> +<!ELEMENT columnfraction (#PCDATA)> +<!ELEMENT thead (row+)> +<!ELEMENT tbody (row+)> +<!ELEMENT row (entry*)> +<!ELEMENT entry (#PCDATA | %Inline.phrase;)*> + +<!-- API definitions --> +<!ELEMENT definition (definitionterm | definitionitem | indexterm)+> +<!ELEMENT definitionterm (%definition.cmds; | indexterm)+> +<!ELEMENT definitionitem (%block;)*> + +<!ELEMENT defcategory (#PCDATA | %Inline.phrase;)*> +<!ELEMENT deffunction (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defvariable (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defparam (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defdelimiter (#PCDATA | %Inline.phrase;)*> +<!ELEMENT deftype (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defparamtype (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defdatatype (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defclass (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defclassvar (#PCDATA | %Inline.phrase;)*> +<!ELEMENT defoperation (#PCDATA | %Inline.phrase;)*> + +<!-- INLINE Elements --> + +<!-- options --> +<!ELEMENT frenchspacing (#PCDATA)> <!-- must be on or off --> +<!ATTLIST frenchspacing val (%onoff;) 'off'> + +<!-- emphasize --> +<!ELEMENT strong (#PCDATA | %Inline.phrase;)*> +<!ELEMENT emph (#PCDATA | %Inline.phrase;)*> + +<!-- small caps --> +<!ELEMENT sc (#PCDATA | %Inline.phrase;)*> + +<!-- fonts --> +<!ELEMENT b (#PCDATA | %Inline.phrase;)*> +<!ELEMENT i (#PCDATA | %Inline.phrase;)*> +<!ELEMENT r (#PCDATA | %Inline.phrase;)*> +<!ELEMENT sansserif (#PCDATA | %Inline.phrase;)*> +<!ELEMENT slanted (#PCDATA | %Inline.phrase;)*> +<!ELEMENT titlefont (#PCDATA | %Inline.phrase;)*> +<!ELEMENT tt (#PCDATA | %Inline.phrase;)*> + +<!-- markup --> +<!ELEMENT code (#PCDATA | %Inline.phrase;)*> +<!ELEMENT command (#PCDATA | %Inline.phrase;)*> +<!ELEMENT env (#PCDATA | %Inline.phrase;)*> +<!ELEMENT file (#PCDATA | %Inline.phrase;)*> +<!ELEMENT option (#PCDATA | %Inline.phrase;)*> +<!ELEMENT samp (#PCDATA | %Inline.phrase;)*> +<!ELEMENT dfn (#PCDATA | %Inline.phrase;)*> +<!ELEMENT cite (#PCDATA | %Inline.phrase;)*> +<!ELEMENT key (#PCDATA | %Inline.phrase;)*> +<!ELEMENT kbd (#PCDATA | %Inline.phrase;)*> +<!ELEMENT var (#PCDATA | %Inline.phrase;)*> +<!ELEMENT url (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT acronym (acronymword, acronymdesc?)> +<!ELEMENT acronymword (#PCDATA | %Inline.phrase;)*> +<!ELEMENT acronymdesc (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT abbrev (abbrevword, abbrevdesc?)> +<!ELEMENT abbrevword (#PCDATA | %Inline.phrase;)*> +<!ELEMENT abbrevdesc (#PCDATA | %Inline.phrase;)*> + +<!-- math --> +<!ELEMENT math (#PCDATA | %Inline.phrase;)*> +<!ELEMENT dmn (#PCDATA | %Inline.phrase;)*> + +<!-- reference --> +<!ELEMENT anchor EMPTY> +<!ATTLIST anchor + name CDATA #IMPLIED> + +<!ELEMENT xref (xrefnodename | xrefinfoname | xrefinfofile + | xrefprintedname | xrefprinteddesc)*> +<!ELEMENT xrefnodename (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefinfoname (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefinfofile (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefprintedname (#PCDATA | %Inline.phrase;)*> +<!ELEMENT xrefprinteddesc (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT inforef (inforefnodename | inforefrefname | inforefinfoname)*> +<!ELEMENT inforefnodename (#PCDATA | %Inline.phrase;)*> +<!ELEMENT inforefrefname (#PCDATA | %Inline.phrase;)*> +<!ELEMENT inforefinfoname (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT synindex EMPTY> +<!ATTLIST synindex + code (yes|no) 'no' + from NMTOKEN #REQUIRED + to NMTOKEN #REQUIRED> +<!ELEMENT indexterm (#PCDATA | %Inline.phrase;)*> +<!ATTLIST indexterm + index CDATA #IMPLIED> + +<!ELEMENT email (emailaddress, emailname?)> +<!ELEMENT emailaddress (#PCDATA | %Inline.phrase;)*> +<!ELEMENT emailname (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT uref (urefurl, urefdesc?, urefreplacement?)> +<!ELEMENT urefurl (#PCDATA | %Inline.phrase;)*> +<!ELEMENT urefdesc (#PCDATA | %Inline.phrase;)*> +<!ELEMENT urefreplacement (#PCDATA | %Inline.phrase;)*> + +<!ELEMENT footnote (para)> + + +<!ELEMENT punct (#PCDATA)> +<!ATTLIST punct + end-of-sentence (yes|no) #IMPLIED> +<!ELEMENT logo (#PCDATA)> +<!ELEMENT linebreak EMPTY> + +<!ENTITY tex "<logo>TeX</logo>"> +<!ENTITY latex "<logo>LaTeX</logo>"> +<!ENTITY ellipsis "…"> +<!ENTITY lt "<"> +<!ENTITY gt ">"> +<!ENTITY bullet "•"> +<!ENTITY copyright "©"> +<!ENTITY registered "®"> +<!ENTITY euro "€"> +<!ENTITY pounds "£"> +<!ENTITY minus "−"> +<!ENTITY linebreak "<linebreak/>"> +<!ENTITY space " "> <!-- Should become an element. --> +<!ENTITY dots "<punct end-of-sentence='no'>…</punct>"> +<!ENTITY enddots "<punct end-of-sentence='yes'>…</punct>"> +<!ENTITY amp "&"> +<!ENTITY lsquo "‘"> +<!ENTITY rsquo "’"> +<!ENTITY sbquo "‚"> +<!ENTITY ldquo "“"> +<!ENTITY rdquo "”"> +<!ENTITY bdquo "„"> +<!ENTITY laquo "«"> +<!ENTITY raquo "»"> +<!ENTITY lsaquo "‹"> +<!ENTITY rsaquo "›"> +<!ENTITY mdash "—"> +<!ENTITY ndash "–"> +<!ENTITY period "<punct end-of-sentence='no'>.</punct>"> +<!ENTITY eosperiod "<punct end-of-sentence='yes'>.</punct>"> +<!ENTITY quest "<punct end-of-sentence='no'>?</punct>"> +<!ENTITY eosquest "<punct end-of-sentence='yes'>?</punct>"> +<!ENTITY excl "<punct end-of-sentence='no'>!</punct>"> +<!ENTITY eosexcl "<punct end-of-sentence='yes'>!</punct>"> + +<!ENTITY auml "ä"> +<!ENTITY ouml "ö"> +<!ENTITY uuml "ü"> +<!ENTITY Auml "Ä"> +<!ENTITY Ouml "Ö"> +<!ENTITY Uuml "Ü"> +<!ENTITY Euml "Ë"> +<!ENTITY euml "ë"> +<!ENTITY Iuml "Ï"> +<!ENTITY iuml "ï"> +<!ENTITY yuml "ÿ"> +<!ENTITY uml "¨"> + +<!ENTITY Aacute "Á"> +<!ENTITY Eacute "É"> +<!ENTITY Iacute "Í"> +<!ENTITY Oacute "Ó"> +<!ENTITY Uacute "Ú"> +<!ENTITY Yacute "Ý"> +<!ENTITY aacute "á"> +<!ENTITY eacute "é"> +<!ENTITY iacute "í"> +<!ENTITY oacute "ó"> +<!ENTITY uacute "ú"> +<!ENTITY yacute "ý"> + +<!ENTITY ccedil "ç"> +<!ENTITY Ccedil "Ç"> + +<!ENTITY Acirc "Â"> +<!ENTITY Ecirc "Ê"> +<!ENTITY Icirc "Ã"> +<!ENTITY Ocirc "Ô"> +<!ENTITY Ucirc "Û"> +<!ENTITY acirc "â"> +<!ENTITY ecirc "ê"> +<!ENTITY icirc "î"> +<!ENTITY ocirc "ô"> +<!ENTITY ucirc "û"> + +<!ENTITY Agrave "À"> +<!ENTITY Egrave "È"> +<!ENTITY Igrave "Ì"> +<!ENTITY Ograve "Ò"> +<!ENTITY Ugrave "Ù"> +<!ENTITY agrave "à"> +<!ENTITY egrave "è"> +<!ENTITY igrave "ì"> +<!ENTITY ograve "ò"> +<!ENTITY ugrave "ù"> + +<!ENTITY Atilde "Ã"> +<!ENTITY Ntilde "Ñ"> +<!ENTITY Otilde "Õ"> +<!ENTITY atilde "ã"> +<!ENTITY ntilde "ñ"> +<!ENTITY otilde "õ"> + +<!ENTITY oslash "ø"> +<!ENTITY Oslash "Ø"> + +<!ENTITY ordm "º"> +<!ENTITY ordf "ª"> + +<!ENTITY iexcl "¡"> +<!ENTITY pound "£"> +<!ENTITY iquest "¿"> +<!ENTITY AElig "Æ"> +<!ENTITY aelig "æ"> +<!ENTITY OElig "Œ"> +<!ENTITY oelig "œ"> +<!ENTITY Aring "Å"> +<!ENTITY aring "å"> +<!ENTITY szlig "ß"> + +<!ENTITY rarr "→"> +<!ENTITY rArr "⇒"> + +<!ENTITY macr "¯"> + + +<!-- fixxme: not yet classified --> + +<!ELEMENT sp (#PCDATA)> +<!ATTLIST sp + lines CDATA #IMPLIED> +<!ELEMENT printindex (#PCDATA)> + diff --git a/util/texinfo.xsl b/util/texinfo.xsl new file mode 100644 index 0000000..5225517 --- /dev/null +++ b/util/texinfo.xsl @@ -0,0 +1,242 @@ +<?xml version='1.0'?> +<!-- $Id: texinfo.xsl,v 1.1 2004/04/11 17:56:47 karl Exp $ --> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + version="1.0"> + +<xsl:output method="html" indent="yes"/> + +<!-- root rule --> +<xsl:template match="/"> + <html> + <head><title> + <xsl:apply-templates select="TEXINFO/SETTITLE" mode="head"/> + </title></head> + <body bgcolor="#FFFFFF"><xsl:apply-templates/> +</body></html> +</xsl:template> + + +<xsl:template match="TEXINFO"> + <xsl:apply-templates/> +</xsl:template> + + +<xsl:template match="TEXINFO/SETFILENAME"> +</xsl:template> + +<xsl:template match="TEXINFO/SETTITLE" mode="head"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="TEXINFO/SETTITLE"> + <h1><xsl:apply-templates/></h1> +</xsl:template> + + +<xsl:template match="TEXINFO/DIRCATEGORY"> +</xsl:template> + +<xsl:template match="//PARA"> + <p><xsl:apply-templates/></p> +</xsl:template> + +<xsl:template match="//EMPH"> + <i><xsl:apply-templates/></i> +</xsl:template> + +<!-- The node --> +<xsl:template match="TEXINFO/NODE"> + <hr/> + <p> + <xsl:apply-templates select="NODENAME" mode="select"/> + <xsl:apply-templates select="NODEPREV" mode="select"/> + <xsl:apply-templates select="NODEUP" mode="select"/> + <xsl:apply-templates select="NODENEXT" mode="select"/> + <xsl:apply-templates/> + <h2>Footnotes</h2> + <ol> + <xsl:apply-templates select=".//FOOTNOTE" mode="footnote"/> + </ol> + </p> +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODENAME" mode="select"> +<h2> + <a> + <xsl:attribute name="name"> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> +</h2> +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODENAME"/> + + +<xsl:template match="TEXINFO/NODE/NODEPREV" mode="select"> + [ <b>Previous: </b> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> ] +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODEPREV"/> + +<xsl:template match="TEXINFO/NODE/NODEUP" mode="select"> + [ <b>Up: </b> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> ] +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODEUP"/> + +<xsl:template match="TEXINFO/NODE/NODENEXT" mode="select"> + [ <b>Next: </b> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates/> + </xsl:attribute> + <xsl:apply-templates/> + </a> ] +</xsl:template> + +<xsl:template match="TEXINFO/NODE/NODENEXT"/> + +<!-- Menu --> +<xsl:template match="//MENU"> + <h3>Menu</h3> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY"> + <a> + <xsl:attribute name="href"> + <xsl:text>#</xsl:text> + <xsl:apply-templates select="MENUNODE"/> + </xsl:attribute> + <xsl:apply-templates select="MENUTITLE"/> + </a>: + <xsl:apply-templates select="MENUCOMMENT"/> + <br/> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY/MENUNODE"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY/MENUTITLE"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//MENU/MENUENTRY/MENUCOMMENT"> + <xsl:apply-templates mode="menucomment"/> +</xsl:template> + +<xsl:template match="PARA" mode="menucomment"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="//PARA"> + <p><xsl:apply-templates/></p> +</xsl:template> + +<!-- LISTS --> +<xsl:template match="//ITEMIZE"> + <ul> + <xsl:apply-templates/> + </ul> +</xsl:template> + +<xsl:template match="//ITEMIZE/ITEM"> + <li> + <xsl:apply-templates/> + </li> +</xsl:template> + +<xsl:template match="//ENUMERATE"> + <ol> + <xsl:apply-templates/> + </ol> +</xsl:template> + +<xsl:template match="//ENUMERATE/ITEM"> + <li> + <xsl:apply-templates/> + </li> +</xsl:template> + +<!-- INLINE --> +<xsl:template match="//CODE"> + <tt> + <xsl:apply-templates/> + </tt> +</xsl:template> + +<xsl:template match="//DFN"> + <i><b> + <xsl:apply-templates/> + </b></i> +</xsl:template> + +<xsl:template match="//STRONG"> + <b> + <xsl:apply-templates/> + </b> +</xsl:template> + +<xsl:template match="//CENTER"> + <center> + <xsl:apply-templates/> + </center> +</xsl:template> + +<xsl:template match="//VAR"> + <i> + <xsl:apply-templates/> + </i> +</xsl:template> + +<xsl:template match="//KBD"> + <tt> + <xsl:apply-templates/> + </tt> +</xsl:template> + +<xsl:template match="//KEY"> + <b> + <xsl:apply-templates/> + </b> +</xsl:template> + +<!-- BLOCKS --> +<xsl:template match="//DISPLAY"> + <pre> + <xsl:apply-templates/> + </pre> +</xsl:template> + + +<!-- INDEX --> +<xsl:template match="//INDEXTERM"> +</xsl:template> + +<!-- FOOTNOTE --> +<xsl:template match="//FOOTNOTE"> +</xsl:template> + +<xsl:template match="//FOOTNOTE" mode="footnote"> + <li><xsl:apply-templates/></li> +</xsl:template> + +</xsl:stylesheet> diff --git a/util/txitextest b/util/txitextest new file mode 100755 index 0000000..4a85b01 --- /dev/null +++ b/util/txitextest @@ -0,0 +1,77 @@ +#!/bin/sh +# $Id: txitextest,v 1.8 2006/08/14 13:18:20 karl Exp $ +# Test texinfo.tex changes by running various manuals through with an +# old version, saving the .ps result from dvips, doing the same with a +# new version, and comparing. Idea from Stepan Kasal. +# +# Another option is to run the manuals all the way through using +# texi2dvi, which tests in another way. + +tsrc=`dirname $0`/.. +PATH=$tsrc/util:$PATH + +tdoc=$tsrc/doc +default_manuals="$tdoc/texinfo.txi $tdoc/info.texi $tdoc/info-stnd.texi" + +olddir=$tsrc/../gnulib/config +newdir=$tdoc +tempdir=$tsrc/@tests/test +full=false +manuals= + +while test $# -gt 0; do + case $1 in + --f*) full=true;; + --o*) shift; olddir="$1";; + --n*) shift; newdir="$1";; + --t*) shift; tempdir="$1";; + -*) echo "$0: unknown option \`$1'." >&2; exit 1;; + *) manuals="$manuals $1";; + esac + shift +done + +test -z "$manuals" && manuals=$default_manuals +initial_dir=`pwd` + +cd $tempdir || exit 1 +rm -f * + +run_tex() \ +{ + TEXINPUTS=.:$mandir: tex $manual \ + || { echo "tex $manual failed." >&2; exit 1; } +} + +for manual in $manuals; do + mandir=`dirname $manual` + test $mandir = . && mandir=$initial_dir + manual_base=`basename "$manual" | sed 's/\.[^.]*$//'` + + rm -rf $manual_base.* texinfo.tex + ln -s $newdir/texinfo.tex texinfo.tex + + if $full; then + # instead of comparing, do full test of just the new texinfo.tex. + echo "$0: testing $manual_base... (tex)" + texi2dvi $manual || { echo "texi2dvi $manual failed." >&2; exit 1; } + echo "$0: testing $manual_base... (pdf)" + texi2dvi --pdf $manual \ + || { echo "texi2dvi --pdf $manual failed." >&2; exit 1; } + + else + echo "$0: testing $manual_base... (new)" + run_tex + dvips $manual_base -o || exit 1 + mv $manual_base.ps new.$manual_base.ps + + echo "$0: testing $manual_base... (old)" + rm -rf $manual_base.* texinfo.tex + ln -s $olddir/texinfo.tex texinfo.tex + run_tex + dvips $manual_base -o || exit 1 + mv $manual_base.ps old.$manual_base.ps + + diff -U0 old.$manual_base.ps new.$manual_base.ps + fi +done |