summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwl <wl>2013-08-11 08:26:58 +0000
committerwl <wl>2013-08-11 08:26:58 +0000
commit8375908f83748c8ed9a611f49da8e973f19badbc (patch)
treec385b1ff64d8f4cdb759bfd0c61c8f65a9a3bd57
parent42a4e0d4d06981b35b42a38e99d1b024e61fb3d7 (diff)
downloadgroff-8375908f83748c8ed9a611f49da8e973f19badbc.tar.gz
Revert last accidental removal of files.
-rw-r--r--contrib/chem/ChangeLog232
-rw-r--r--contrib/chem/Makefile.sub112
-rw-r--r--contrib/chem/README.txt52
-rw-r--r--contrib/chem/chem.man1017
-rw-r--r--contrib/chem/chem.pic94
-rwxr-xr-xcontrib/chem/chem.pl1274
-rw-r--r--contrib/chem/examples/README.txt65
-rw-r--r--contrib/chem/examples/atp.chem63
-rw-r--r--contrib/chem/examples/cholesterin.chem52
-rw-r--r--contrib/chem/examples/ethamivan.chem48
-rw-r--r--contrib/chem/examples/lsd.chem51
-rw-r--r--contrib/chem/examples/morphine.chem55
-rw-r--r--contrib/chem/examples/penicillin.chem56
-rw-r--r--contrib/chem/examples/reserpine.chem65
-rw-r--r--contrib/groffer/ChangeLog314
-rw-r--r--contrib/groffer/Makefile.sub149
-rw-r--r--contrib/groffer/README123
-rw-r--r--contrib/groffer/roff2.man249
-rw-r--r--contrib/groffer/version.sh38
19 files changed, 4109 insertions, 0 deletions
diff --git a/contrib/chem/ChangeLog b/contrib/chem/ChangeLog
new file mode 100644
index 00000000..a631d27b
--- /dev/null
+++ b/contrib/chem/ChangeLog
@@ -0,0 +1,232 @@
+2013-01-29 Werner LEMBERG <wl@gnu.org>
+
+ * Makefile.sub (MOSTLYCLEANADD): Fix typo.
+
+2010-12-13 Werner LEMBERG <wl@gnu.org>
+
+ Really fix handling of examples/122.
+
+ * examples/122/README: Renamed to...
+ * examples/122/README.txt: This.
+
+ * Makefile.sub (all, MOSTLYCLEANADD): Add `examples/122/README'.
+ (examples/122/README): New target.
+ (install_data): Fix typo.
+
+2010-06-02 Larry Jones <lawrence.jones@siemens.com>
+
+ * Makefile.sub (install): Fix handling of examples/122.
+ It tried to process the CVS subdirectory as a file.
+
+2009-01-03 Werner LEMBERG <wl@gnu.org>
+
+ * chem.pl: Prepare for groff version 1.20.
+
+2008-01-04 Werner LEMBERG <wl@gnu.org>
+
+ * chem.man: Insert `\:' in URLs where appropriate.
+
+2007-02-06 Eric S. Raymond <esr@snark.thyrsus.com>
+
+ * chem.man: Change .UR/.UE and .MT/.ME so the start macro no longer
+ takes a second argument that is pasted to the end of the generated
+ text. Instead, the end macro takes an argument that does the same
+ thing.
+
+2007-02-02 Werner LEMBERG <wl@gnu.org>
+
+ * chem.man: Further refinements and normalizations.
+
+2007-02-02 Eric S. Raymond <esr@snark.thyrsus.com>
+
+ * chem.man: Converted to use .SY/.OP/.YS and for cross-viewer
+ portability. Conversion checked using the protocol described in
+ tmac/TESTING-HINTS.
+
+2006-11-10 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of chem 0.3.1
+
+ * chem.man: Add information about example files.
+
+2006-11-10 Werner LEMBERG <wl@gnu.org>
+
+ * chem.man1: Rename back to...
+ * chem.man: This.
+ Use @G@, @MACRODIR@, and @DATASUBDIR@.
+
+ * Makefile.sub (CLEANADD, all): Don't handle chem.man.
+ (chem.man): Remove rule.
+ (chem): s/tmacdir/MACRODIR/, s/picdir/PICDIR/.
+
+ * chem.pl: s/tmacdir/MACRODIR/, s/picdir/PICDIR/.
+
+2006-11-10 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of chem 0.3.0
+
+ * chem.man1: Rename `chem.man' to translate some `@...@'
+ constructs. Some minor corrections. Remove some unused macros.
+
+ * examples/README.txt, examples/122/README: Add information on
+ `roff2*' programs.
+
+ * chem.pic: Rename `macros.pic'.
+
+ * Makefile.sub, chem.pl: Replace `macros.pic' by `chem.pic'.
+
+2006-11-09 Werner LEMBERG <wl@gnu.org>
+
+ * chem.man: Revised.
+
+2006-11-08 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of chem 0.2.0
+
+ * pic.tmac: Remove this file. Use instead the installed pic.tmac
+ in $(tmacdir).
+
+ * Makefile.sub, chem.pl:
+ - Install macros.pic to $(tmacdir)/pic/chem.pic.
+ - Remove parts with `libdir'.
+
+2006-11-07 Werner LEMBERG <wl@gnu.org>
+
+ * Makefile.sub: Add and fix $(srcdir) where necessary to make it
+ compile with srcdir != builddir. Other minor fixes improvements.
+
+2006-11-07 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of chem 0.1.2
+
+ ### `chem' works now with all example files (examples/*.chem and
+ examples/122/*.chem).
+
+ * examples/122/README: Add some information on the example files.
+
+ * examples/122/chAi_poly_vinyl_chloride.chem: Use .ps with
+ argument `-2' and recall `.ps +2' at the end of the file. This
+ stops the size shift in the following files.
+
+ * examples/122/ch6b_dna.chem: Make the file runnable, it works
+ now.
+
+ * examples/reserpine.chem: Change access to `begin chem'.
+
+ * chem.man:
+ - Fix the BUGS section.
+ - Correct the name of the macro file to `macros.pic'.
+ - Extent section DESCRIPTION and LANGUAGE.
+ - Moieties and Strings: Rewritten section about moieties and
+ double quoted strings.
+
+ * chem.pl:
+ - parameter check: Add filespecs only when non-empty file.
+ - Set $Last_Type to $OTHER for the `pic' command.
+ - joinring(), label(), labsave(), reduce(): Remove these functions.
+ - `[', `]', `{', `}', `define': Make these and the defined
+ functions commands for `chem' without using the `pic' word.
+ - @Words: Fix it such that all double quoted strings are
+ completely in an element.
+ - `Last: ': Remove this prefix from all commands that are related
+ to `pic'.
+
+ ### global variables
+
+ * chem.pl:
+ - $Line: Add this variable to store the unchanged input line.
+ - %Params: Add the variables from setparams() to this hash.
+ - %Types: Add BOND, MOL, RING, OTHER from init() to this hash.
+ - %Put: Move %put to this.
+ - %Dbl: Move %dbl to this.
+ - %Labtype: Move %labtype to this.
+ - %Aromatic: Move $aromatic to this.
+ - %Dc: Move %dc to this.
+ - %Nput: Move $nput to this.
+ - %Define: New hash for storing the names of the `define'
+ constructs during `chem'. Use the elements in `%Define' as `chem'
+ commands.
+
+2006-10-27 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of chem 0.1.1
+
+ * chem.pl:
+ - Add handling of `[' and `]' (extension of chem awk).
+ - Restrict line break after labels.
+
+ * ChangeLog: Correct the former entry.
+
+2006-10-26 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of chem 0.1.0
+
+ ### Extensions to the chem awk version.
+
+ * chem.pl:
+ - parameters: -h, --help, -v, --version, -- are added as options.
+ The minus character - is added as filespec for standard input, it
+ may be used several times.
+ - remove the functions `inline', `shiftfields', and `set'.
+ - Fix the handling of the initialization commands .PS, .cstart,
+ `begin chem', and `end'.
+ - Add error massages.
+ - error(): Add file name.
+ - Add concatenation of lines with final backslash `\'.
+ - Add pic.tmac to guarantee that each pic display is centered.
+ - Warnings and strict are active.
+
+ ### Source files of the chem Perl version
+
+ * chem.pl: Source file for the Perl version of chem.
+
+ * macros.pic: Pic macro file that is loaded by each run of chem.
+
+ * pic.tmac: Macro file for .PS and .PE; taken over from the groff
+ source file <groff-top-source>/tmac/pic.tmac.
+
+ * Makefile.sub: Make file for the groff system.
+
+ * ChangeLog: This file.
+
+ * chem.man: Manual page for the Perl version of chem.
+
+ * README.txt: File for information on this chem version.
+
+ * examples/*.chem: Self-constructed example files for chem.
+
+ * examples/README.txt: Information on the example files.
+
+ * examples/122/*.chem: Example files from the classical chem book
+ 122.ps at <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+ * examples/122/README: Information on the example files in this
+ directory.
+
+2006-10-16 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * awk version of chem
+ chem is a roff preprocessor that generates chemical structure
+ diagrams suitable for the pic preprocessor. The original version
+ of chem is an awk script written by Brian Kernighan. This project
+ is a rewrite of chem in Perl.
+
+2006-10-15 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ License
+
+ Copyright (C) 2006-2010, 2013
+ Free Software Foundation, Inc.
+ Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+ Copying and distribution of this file, with or without
+ modification, are permitted provided the copyright notice and this
+ notice are preserved.
+
+ This file is part of `chem', which is part of the `groff' project.
+
+ ####### Emacs settings
+
+ Local Variables:
+ mode: change-log
+ End:
diff --git a/contrib/chem/Makefile.sub b/contrib/chem/Makefile.sub
new file mode 100644
index 00000000..95caed3a
--- /dev/null
+++ b/contrib/chem/Makefile.sub
@@ -0,0 +1,112 @@
+# Makefile.sub for `chem' (integration into the `groff' source tree)
+
+# File position: <groff-source>/contrib/chem/Makefile.sub
+
+# Copyright (C) 2006, 2009, 2010, 2013 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 29 Jan 2013
+
+# This file is part of `chem' which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+########################################################################
+
+MAN1=chem.n
+MOSTLYCLEANADD=\
+ chem \
+ chem.n \
+ README \
+ examples/README \
+ examples/122/README
+
+# not all make programs have $(RM) predefined.
+RM=rm -f
+
+all: README examples/README examples/122/README \
+ chem \
+ $(MAN1)
+
+README: $(srcdir)/README.txt
+ sed -e "s|@g@|$(g)|g" $? >$@
+
+examples/README: $(srcdir)/examples/README.txt
+ -test -d examples || $(mkinstalldirs) examples
+ sed -e "s|@g@|$(g)|g" $? >$@
+
+examples/122/README: $(srcdir)/examples/122/README.txt
+ -test -d examples || $(mkinstalldirs) examples
+ -test -d examples/122 || $(mkinstalldirs) examples/122
+ sed -e "s|@g@|$(g)|g" $? >$@
+
+chem: $(srcdir)/chem.pl $(SH_DEPS_SED_SCRIPT)
+ sed -f "$(SH_DEPS_SED_SCRIPT)" \
+ -e "s|@g@|$(g)|g" \
+ -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \
+ -e "s|@MACRODIR@|$(DESTDIR)$(tmacdir)|g" \
+ -e "s|@PICDIR@|$(DESTDIR)$(datasubdir)/pic|g" \
+ -e "s|@VERSION@|$(version)$(revision)|g" \
+ -e "$(SH_SCRIPT_SED_CMD)" \
+ $(srcdir)/chem.pl >$@
+ chmod +x $@
+
+install_data: chem \
+ README examples/README examples/122/README \
+ $(srcdir)/chem.pic \
+ $(srcdir)/examples/*.chem $(srcdir)/examples/122/*.chem
+ -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir)
+ $(RM) $(DESTDIR)$(bindir)/$(g)chem
+ $(INSTALL_SCRIPT) chem $(DESTDIR)$(bindir)/$(g)chem
+ -test -d $(DESTDIR)$(datasubdir)/pic \
+ || $(mkinstalldirs) $(DESTDIR)$(datasubdir)/pic
+ $(RM) $(DESTDIR)$(datasubdir)/pic/chem.pic
+ $(INSTALL_DATA) $(srcdir)/chem.pic \
+ $(DESTDIR)$(datasubdir)/pic/chem.pic
+ -test -d $(DESTDIR)$(exampledir)/chem \
+ || $(mkinstalldirs) $(DESTDIR)$(exampledir)/chem
+ -test -d $(DESTDIR)$(exampledir)/chem/122 \
+ || $(mkinstalldirs) $(DESTDIR)$(exampledir)/chem/122
+ -$(RM) $(DESTDIR)$(exampledir)/chem/*
+ $(INSTALL_DATA) examples/README \
+ $(DESTDIR)$(exampledir)/chem/README
+ for i in $(srcdir)/examples/*.chem; do \
+ n=`echo $$i | sed 's|$(srcdir)/examples/||g'`; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(exampledir)/chem/$$n; \
+ done
+ -$(RM) $(DESTDIR)$(exampledir)/chem/122/*
+ $(INSTALL_DATA) examples/122/README \
+ $(DESTDIR)$(exampledir)/chem/122/README
+ for i in $(srcdir)/examples/122/*.chem; do \
+ n=`echo $$i | sed 's|$(srcdir)/examples/122/||g'`; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(exampledir)/chem/122/$$n; \
+ done
+
+uninstall_sub:
+ $(RM) $(DESTDIR)$(bindir)/chem
+ $(RM) $(DESTDIR)$(datasubdir)/pic/chem.pic
+ -rmdir $(DESTDIR)$(datasubdir)/pic
+ $(RM) $(DESTDIR)$(exampledir)/chem/122/*
+ -rmdir $(DESTDIR)$(exampledir)/chem/122
+ $(RM) $(DESTDIR)$(exampledir)/chem/*
+ -rmdir $(DESTDIR)$(exampledir)/chem
+ -rmdir $(DESTDIR)$(exampledir)
+
+########################################################################
+# Emacs settings
+########################################################################
+#
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/contrib/chem/README.txt b/contrib/chem/README.txt
new file mode 100644
index 00000000..25518453
--- /dev/null
+++ b/contrib/chem/README.txt
@@ -0,0 +1,52 @@
+`chem' is a `roff' language to generate chemical structure diagrams.
+`@g@chem' is a `groff' preprocessor that produces output suitable for
+the `@g@pic' preprocessor.
+
+The original version of `chem' is an `awk' script written by Brian
+Kernighan <http://cm.bell-labs.com/cm/cs/who/bwk/index.html>. The
+source files of the `awk' version of `chem' are available at
+<http://cm.bell-labs.com/netlib/typesetting/chem.gz>.
+
+This project is a rewrite of `chem' in Perl for the GNU `roff' project
+`groff'. It was written under Perl v5.8.8, but at least Perl v5.6 is
+needed to run the Perl version of `chem'.
+
+In comparison to the original `awk' version of `chem', the Perl
+version does the following changements:
+- the options -h, --help, -v, --version to output usage and version
+information are added.
+- remove some functions `inline', `shiftfields', and `set' and some
+variables that are used only once.
+
+The subdirectory `examples/' contains example files for chem. They
+are written in the `chem' language. The file names end with .chem.
+
+
+####### License
+
+Last update: 5 Jan 2009
+
+Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+This file is part of `chem', which is part of `groff'.
+
+`groff' 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.
+
+`groff' 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/>.
+
+
+####### Emacs settings
+
+Local Variables:
+mode: text
+End:
diff --git a/contrib/chem/chem.man b/contrib/chem/chem.man
new file mode 100644
index 00000000..b2bf7540
--- /dev/null
+++ b/contrib/chem/chem.man
@@ -0,0 +1,1017 @@
+.ig
+@g@chem.1 - man page for @g@chem (section 1).
+
+Source file position: <groff_source_top>/contrib/chem/chem.man
+Installed position: $prefix/share/man/man1/@g@chem.1
+
+Last update: 05 Jan 2009
+..
+.
+.
+.de au
+This file was written by Bernd Warken <groff-bernd.warken-72@web.de>.
+It is based on the documentation of
+.UR http://\:cm.bell-labs.com/\:cm/\:cs/\:who/\:bwk/\:index.html
+Brian Kernighan
+.UE 's
+original
+.I awk
+version of
+.IR chem .
+..
+.
+.
+.de co
+Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+.
+.
+.P
+This file is part of
+.IR chem ,
+which is part of
+.IR groff ,
+a free software project.
+.
+You can redistribute it and/or modify it under the terms of the
+.nh
+.B "GNU General Public License"
+.hy
+as published by the
+.nh
+.BR "Free Software Foundation" ,
+.hy
+either version\~2, or (at your option) any later version.
+.
+.
+.P
+You should have received a copy of the \f(CRGNU General Public
+License\fP along with
+.IR groff ,
+see the files \%\f(CBCOPYING\fP and \%\f(CBLICENSE\fP in the top
+directory of the
+.I groff
+source package.
+.
+Or read the
+.I man page
+.BR gpl (1).
+You can also write to the
+.nh
+.B "Free Software Foundation, 51 Franklin St - Fifth Floor, Boston,"
+.BR "MA 02110-1301, USA" .
+.hy
+..
+.
+.
+.\" --------------------------------------------------------------------
+.\" Local macro definitions
+.
+.ds El \&.\|.\|.\&
+.
+.\" .File_name (<path_name>)
+.\"
+.\" Display a file or directory name in CB font.
+.\"
+.de FN
+. CB \\$@
+..
+.
+.\" .CB (<path_name>)
+.\"
+.\" Display a line in CB font, for example after .TP
+.\"
+.de CB
+.nh
+\\&\\f(CB\\$1\\fP\\$2
+.hy
+..
+.
+.\" End of macro definitions
+.
+.
+.TH @G@CHEM @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@"
+.SH NAME
+@g@chem \- groff preprocessor for producing chemical structure diagrams
+.
+.
+.SH "SYNOPSIS"
+.\" --------------------------------------------------------------------
+.\" SH "SYNOPSIS"
+.\" --------------------------------------------------------------------
+.
+.SY @g@chem
+.RI [ "\%option" \*(El]
+.OP \-\-
+.RI [ "\%filespec" \*(El]
+.
+.SY @g@chem
+.B \-h
+|
+.B \-\-help
+.
+.SY @g@chem
+.B \-v
+|
+.B \-\-version
+.YS
+.
+.
+.\" --------------------------------------------------------------------
+.SH OPTION USAGE
+.\" --------------------------------------------------------------------
+.
+.P
+There are no other options than
+.BR \-h ,
+.BR \-\-help ,
+.BR \-v ,
+and
+.BR \%\-\-version ;
+these options provoke the printing of a version or usage information,
+respectively, and all
+.I filespec
+arguments are ignored.
+.
+A
+.I filespec
+argument is either a file name of an existing file or a minus
+character
+.BR \- ,
+meaning standard input.
+.
+If no argument is specified then standard input is taken
+automatically.
+.
+.
+.\" --------------------------------------------------------------------
+.SH DESCRIPTION
+.\" --------------------------------------------------------------------
+.
+.I chem
+produces chemical structure diagrams.
+.
+Today's version is best suited for organic chemistry (bonds, rings).
+.
+The
+.B @g@chem
+program is a
+.B groff
+preprocessor like
+.BR @g@eqn ,
+.BR @g@pic ,
+.BR @g@tbl ,
+etc.
+.
+It generates
+.I pic
+output such that all
+.I chem
+parts are translated into diagrams of the
+.I pic
+language.
+.
+.
+.P
+The program
+.B @g@chem
+originates from the Perl source file
+.FN chem.pl .
+It tells
+.B @g@pic
+to include a copy of the macro file
+.FN chem.pic .
+.
+Moreover the
+.I groff
+source file
+.FN pic.tmac
+is loaded.
+.
+.
+.P
+In a style reminiscent of
+.I eqn
+and
+.IR pic ,
+the
+.I chem
+diagrams are written in a special language.
+.
+.
+.P
+A set of
+.I chem
+lines looks like this
+.
+.
+.IP
+.nf
+.ft B
+\&.cstart
+\fIchem data\fP
+\&.cend
+.ft
+.fi
+.
+.
+.P
+Lines containing the keywords
+.B .cstart
+and
+.B .cend
+start and end the input for
+.BR @g@chem ,
+respectively.
+.
+In
+.I pic
+context, i.e., after the call of
+.BR .PS ,
+.I chem
+input can optionally be started by the line
+.B \%begin\~chem
+and ended by the line with the single word
+.B end
+instead.
+.
+.
+.P
+Anything outside these initialization lines is copied through
+without modification;
+all data between the initialization lines is converted into
+.I pic
+commands to draw the diagram.
+.
+.
+.P
+As an example,
+.
+.IP
+.nf
+.ft B
+\&.cstart
+CH3
+bond
+CH3
+\&.cend
+.ft
+.fi
+.
+.
+.P
+prints two
+.B CH3
+groups with a bond between them.
+.
+.
+.P
+To actually view this, you must run
+.B @g@chem
+followed by
+.BR groffer :
+.
+.IP
+.B "@g@chem [file\*(El] | groffer"
+.
+.P
+If you want to create just
+.B groff
+output, you must run
+.B @g@chem
+followed by
+.B groff
+with the option
+.B \-p
+for the activation of
+.BR @g@pic :
+.IP
+.B "@g@chem [file\*(El] | groff -p \*(El"
+.
+.
+.\" --------------------------------------------------------------------
+.SH THE LANGUAGE
+.\" --------------------------------------------------------------------
+.
+The
+.I chem
+input language is rather small. It provides rings of several styles
+and a way to glue them together as desired, bonds of several styles,
+moieties (e.g.,
+.BR C ,
+.BR NH3 ,
+\*(El), and strings.
+.
+.
+.\" --------------------------------------------------------------------
+.SS Setting Variables
+.\" --------------------------------------------------------------------
+.
+There are some variables that can be set by commands.
+.
+Such commands have two possible forms, either
+.
+.RS
+.P
+.I "variable value"
+.RE
+.
+.P
+or
+.
+.RS
+.P
+.IB "variable " = " value"
+.RE
+.
+.P
+This sets the given
+.I variable
+to the argument
+.IR value .
+If more arguments are given only the last argument is taken, all other
+arguments are ignored.
+.
+.
+.P
+There are only a few variables to be set by these commands:
+.
+.TP
+.BI textht " arg"
+Set the height of the text to
+.IR arg ;
+default is 0.16.
+.
+.TP
+.BI cwid " arg"
+Set the character width to
+.IR arg ;
+default is 0.12.
+.
+.TP
+.BI db " arg"
+Set the bond length to
+.IR arg ;
+default is 0.2.
+.
+.TP
+.BI size " arg"
+Scale the diagram to make it look plausible at point size
+.IR arg ;
+default is 10 point.
+.
+.
+.\" --------------------------------------------------------------------
+.SS Bonds
+.\" --------------------------------------------------------------------
+.
+This
+.
+.RS
+.SY bond
+.RI [ direction ]
+.RI [ length\ n ]
+.RB [ from\ \c
+.IR Name | picstuff ]
+.YS
+.RE
+.
+.P
+draws a single bond in direction from nearest corner of
+.IR Name .
+.B bond
+can also be
+.BR "double bond" ,
+.BR "front bond" ,
+.BR "back bond" ,
+etc.
+.
+(We will get back to
+.I Name
+soon.)
+.
+.
+.P
+.I direction
+is the angle in degrees (0\~up, positive clockwise)
+or a direction word like
+.BR up ,
+.BR down ,
+.B sw
+(=\~southwest), etc.
+.
+If no direction is specified, the bond goes in the current direction
+(usually that of the last bond).
+.
+.
+.P
+Normally the bond begins at the last object placed; this
+can be changed by naming a
+.B from
+place.
+.
+For instance, to make a simple alkyl chain:
+.
+.RS
+.TS
+tab (@);
+lb l.
+CH3
+bond@(this one goes right from the CH3)
+C@(at the right end of the bond)
+double bond up@(from the C)
+O@(at the end of the double bond)
+bond right from C
+CH3
+.TE
+.RE
+.
+.
+.P
+A length in inches may be specified to override the default length.
+.
+Other
+.I pic
+commands can be tacked on to the end of a bond command, to created
+dotted or dashed bonds or to specify a
+.B to
+place.
+.
+.
+.\" --------------------------------------------------------------------
+.SS Rings
+.\" --------------------------------------------------------------------
+.
+There are lots of rings, but only 5 and 6-sided rings get
+much support.
+.
+.B ring
+by itself is a 6-sided ring;
+.B benzene
+is the benzene ring with a circle inside.
+.B aromatic
+puts a circle into any kind of ring.
+.
+.RS
+.SY ring
+.RB [ \%pointing\ ( up | right | left | down )]
+.RB [ \%aromatic ]
+.RB [ put\ Mol\ at\ \fIn\fP ]
+.RB [ \%double\ \c
+.IR i , j\ \c
+.IR k , l\ \c
+\*(El]
+.RI [ picstuff ]
+.YS
+.RE
+.
+.
+.P
+The vertices of a ring are numbered 1, 2, \*(El from the
+vertex that points in the natural compass direction.
+.
+So for a hexagonal ring with the point at the top, the top vertex
+is\~1, while if the ring has a point at the east side, that is
+vertex\~1.
+.
+This is expressed as
+.
+.IP
+.ft B
+.nf
+R1: ring pointing up
+R2: ring pointing right
+.fi
+.ft
+.
+.
+.P
+The ring vertices are named
+.BR .V1 ,
+\*(El,
+.BI .V n\fR,\fP
+with
+.B .V1
+in the pointing direction.
+.
+So the corners of
+.B R1
+are
+.B R1.V1
+(the
+.IR top ),
+.BR R1.V2 ,
+.BR R1.V3 ,
+.B R1.V4
+(the
+.IR bottom ),
+etc., whereas for
+.BR R2 ,
+.B R2.V1
+is the rightmost vertex and
+.B R2.V4
+the leftmost.
+.
+These vertex names are used for connecting bonds or other rings. For
+example,
+.
+.IP
+.ft B
+.nf
+R1: benzene pointing right
+R2: benzene pointing right with .V6 at R1.V2
+.fi
+.ft
+.P
+creates two benzene rings connected along a side.
+.
+.
+.P
+Interior double bonds are specified as
+.BI \%double\ n1 , n2\ n3 , n4\ \fR\*(El;\fP
+each number pair adds an interior bond.
+.
+So the alternate form of a benzene ring is
+.
+.IP
+.B "ring double 1,2 3,4 5,6"
+.
+.
+.P
+Heterocycles (rings with something other than carbon at a vertex) are
+written as
+.BI put\ X\ at\ V\fR,\fP
+as in
+.
+.IP
+.B "R: ring put N at 1 put O at 2"
+.
+.
+.P
+In this heterocycle,
+.B R.N
+and
+.B R.O
+become synonyms for
+.B R.V1
+and
+.BR R.V2 .
+.
+.
+.P
+There are two 5-sided rings.
+.
+.B ring5
+is pentagonal with a side that matches the 6-sided ring; it has four
+natural directions.
+.
+A
+.B \%flatring
+is a 5-sided ring created by chopping one corner of a 6-sided ring so
+that it exactly matches the 6-sided rings.
+.
+.
+.P
+The description of a ring has to fit on a single line.
+.
+.
+.\" --------------------------------------------------------------------
+.SS Moieties and Strings
+.\" --------------------------------------------------------------------
+.
+A moiety is a string of characters beginning with a capital letter,
+such as N(C2H5)2.
+.
+Numbers are converted to subscripts (unless they appear to be
+fractional values, as in N2.5H).
+.
+The name of a moiety is determined from the moiety after special
+characters have been stripped out: e.g., N(C2H5)2) has the name NC2H52.
+.
+.
+.P
+Moieties can be specified in two kinds.
+.
+Normally a moiety is placed right after the last thing mentioned,
+separated by a semicolon surrounded by spaces, e.g.,
+.
+.IP
+.B "B1: bond ; OH"
+.
+.P
+Here the moiety is
+.BR OH ;
+it is set after a bond.
+.
+.
+.P
+As the second kind a moiety can be positioned as the first word in a
+.IR pic -like
+command, e.g.,
+.
+.IP
+.B "CH3 at C + (0.5,0.5)"
+.
+.P
+Here the moiety is
+.BR CH3 .
+It is placed at a position relative to
+.BR C ,
+a moiety used earlier in the chemical structure.
+.
+.
+.P
+So moiety names can be specified as
+.I chem
+positions everywhere in the
+.I chem
+code.
+.
+Beneath their printing moieties are names for places.
+.
+.
+.P
+The moiety
+.B BP
+is special.
+.
+It is not printed but just serves as a mark to be referred to in later
+.I chem
+commands.
+.
+For example,
+.
+.IP
+.B "bond ; BP"
+.
+.P
+sets a mark at the end of the bond.
+.
+This can be used then for specifying a place.
+.
+The name
+.B BP
+is derived from
+.I branch point
+(i.e., line crossing).
+.
+.
+.P
+A string within double quotes
+.B \(dq
+is interpreted as a part of a
+.I chem
+command.
+.
+It represents a string that should be printed (without the quotes).
+.
+Text within quotes \(dq\*(El\(dq is treated more or less
+like a moiety except that no changes are made to the quoted part.
+.
+.
+.\" --------------------------------------------------------------------
+.SS Names
+.\" --------------------------------------------------------------------
+.
+In the alkyl chain above, notice that the carbon atom
+.B C
+was used both to draw something and as the name for a place.
+.
+A moiety always defines a name for a place; you can use
+your own names for places instead, and indeed, for rings
+you will have to.
+.
+A name is just
+.
+.IP
+.IB Name :
+\*(El
+.
+.
+.P
+.I Name
+is often the name of a moiety like
+.BR CH3 ,
+but it need not to be.
+.
+Any name that begins with a capital letter and which contains
+only letters and numbers is valid:
+.
+.RS
+.TP
+.B First:
+.B bond
+.TQ
+\&
+.B "bond 30 from First"
+.RE
+.
+.
+.\" --------------------------------------------------------------------
+.SS Miscellaneous
+.\" --------------------------------------------------------------------
+.
+The specific construction
+.RS
+.TP
+.BR bond\ \*(El " ; moiety"
+.RE
+.P
+is equivalent to
+.IP
+.ft B
+.nf
+bond
+moiety
+.fi
+.ft
+.
+.
+.P
+Otherwise, each item has to be on a separate line (and only one line).
+Note that there must be whitespace after the semicolon which separates
+the commands.
+.
+.
+.P
+A period character
+.B .\&
+or a single quote
+.B '
+in the first column of a line signals a
+.I troff
+command, which is copied through as-is.
+.
+.
+.P
+A line whose first non-blank character is a hash character
+.RB ( # )
+is treated as a comment and thus ignored.
+.
+However, hash characters within a word are kept.
+.
+.
+.P
+A line whose first word is
+.B pic
+is copied through as-is after the word
+.B pic
+has been removed.
+.
+.
+.P
+The command
+.IP
+.B size
+.I n
+.P
+scales the diagram to make it look plausible at point size\~\c
+.I n
+(default is 10\~point).
+.
+.
+.P
+Anything else is assumed to be
+.I pic
+code, which is copied through with a label.
+.
+.
+.P
+Since
+.B @g@chem
+is a
+.B @g@pic
+preprocessor, it is possible to include
+.I pic
+statements in the middle of a diagram to draw things not provided for
+by
+.I chem
+itself.
+.
+Such
+.I pic
+statements should be included in
+.I chem
+code by adding
+.B pic
+as the first word of this line for clarity.
+.
+.
+.P
+The following
+.I pic
+commands are accepted as
+.I chem
+commands, so no
+.B pic
+command word is needed:
+.
+.IP
+.B define
+Start the definition of
+.I pic
+macro within
+.IR chem .
+.
+.RS
+.TP
+.B [
+Start a block composite.
+.
+.TP
+.B ]
+End a block composite.
+.
+.TP
+.B {
+Start a macro definition block.
+.
+.TP
+.B }
+End a macro definition block.
+.RE
+.
+.P
+The macro names from
+.B define
+statements are stored and their call is accepted as a
+.I chem
+command as well.
+.
+.
+.\" --------------------------------------------------------------------
+.SS WISH LIST
+.\" --------------------------------------------------------------------
+.
+.P
+This TODO list was collected by Brian Kernighan.
+.
+.
+.P
+Error checking is minimal; errors are usually detected and reported in
+an oblique fashion by
+.IR pic .
+.
+.
+.P
+There is no library or file inclusion mechanism, and there is no
+shorthand for repetitive structures.
+.
+.
+.P
+The extension mechanism is to create
+.I pic
+macros, but these are tricky to get right and don't have all the
+properties of built-in objects.
+.
+.
+.P
+There is no in-line chemistry yet (e.g., analogous to the $\*(El$
+construct of eqn).
+.
+.
+.P
+There is no way to control entry point for bonds on groups.
+.
+Normally a bond connects to the carbon atom if entering from
+the top or bottom and otherwise to the nearest corner.
+.
+.
+.P
+Bonds from substituted atoms on heterocycles do not join at the proper
+place without adding a bit of
+.IR pic .
+.
+.
+.P
+There is no decent primitive for brackets.
+.
+.
+.P
+Text (quoted strings) doesn't work very well.
+.
+.
+.P
+A squiggle bond is needed.
+.
+.
+.\" --------------------------------------------------------------------
+.SH "FILES"
+.\" --------------------------------------------------------------------
+.
+.TP
+.FN @DATASUBDIR@/pic/chem.pic
+A collection of
+.I pic
+macros needed by
+.BR @g@chem .
+.
+.TP
+.FN @MACRODIR@/pic.tmac
+A macro file which redefines
+.B .PS
+and
+.BR .PE
+to center
+.I pic
+diagrams.
+.
+.TP
+.FN @DOCDIR@/examples/chem/*.chem
+Example files for
+.IR chem .
+.
+.TP
+.FN @DOCDIR@/examples/chem/122/*.chem
+Example files from the classical
+.I chem
+book
+.BR 122.ps .
+.
+.
+.\" --------------------------------------------------------------------
+.SH "BUGS"
+.\" --------------------------------------------------------------------
+.
+Report bugs to the
+.MT bug-groff@\:gnu.org
+bug-groff mailing list
+.ME .
+.
+Include a complete, self-contained example that will allow the bug to
+be reproduced, and say which version of
+.I groff
+and
+.I chem
+you are using.
+.
+You can get both version numbers by calling
+.BR "@g@chem --version" .
+.
+.
+.P
+You can also use the
+.MT groff@\:gnu.org
+groff mailing list
+.ME ,
+but you must first subscribe to this list.
+.
+You can do that by visiting the
+.UR http://\:lists.gnu.org/\:mailman/\:listinfo/\:groff
+groff mailing list web page
+.UE .
+.
+.
+.P
+See
+.BR \%groff (@MAN1EXT@)
+for information on availability.
+.
+.
+.\" --------------------------------------------------------------------
+.SH "SEE ALSO"
+.\" --------------------------------------------------------------------
+.
+.BR \%groff (@MAN1EXT@),
+.BR \%@g@pic (@MAN1EXT@),
+.BR \%groffer (@MAN1EXT@).
+.
+.
+.P
+You can still get the original
+.UR http://\:cm.bell-labs.com/\:netlib/\:typesetting/\:chem.gz
+chem awk source
+.UE .
+.
+Its
+.FN README
+file was used for this manual page.
+.
+.
+.P
+The other classical document on
+.I chem
+is
+.UR http://\:cm.bell-labs.com/\:cm/\:cs/\:cstr/\:122.ps.gz
+122.ps
+.UE .
+.
+.
+.\" --------------------------------------------------------------------
+.SH "AUTHOR"
+.\" --------------------------------------------------------------------
+.au
+.
+.
+.\" --------------------------------------------------------------------
+.SH "COPYING"
+.\" --------------------------------------------------------------------
+.co
+.
+.
+.\" --------------------------------------------------------------------
+.\" Emacs settings
+.\" --------------------------------------------------------------------
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/contrib/chem/chem.pic b/contrib/chem/chem.pic
new file mode 100644
index 00000000..d34c7329
--- /dev/null
+++ b/contrib/chem/chem.pic
@@ -0,0 +1,94 @@
+# macros for chem
+
+# Source file position: <groff-source>/contrib/chem/chem.pic
+# Installed position: <prefix>/share/groff/<version>/pic
+
+# Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
+# Written by Brian Kernighan <http://cm.bell-labs.com/cm/cs/who/bwk>,
+# modified by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+########################################################################
+
+pi = 3.141592654
+deg = 57.29578
+# cr = 0.08 # radius of invis circle at ring vertices (see cr[vh])
+# crh = 0.16; crw = 0.12 # ht & wid of invis ellipse around atoms at ring vertices
+# dav = 0.015 # vertical shift up for atoms in atom macro
+
+# atom(text, wid, ht, carbon position, crh, crw, dav)
+define atom { [
+ T: $1 wid $2 ht $3-2*$7
+ C: ellipse invis ht $5 wid $6 at T.w + ($4,$7)
+ L: ellipse invis ht $5 wid $6 at T.w + (cwid/2,$7)
+ R: ellipse invis ht $5 wid $6 at T.e + (-cwid/2,$7)
+] }
+
+# bond(length, angle in degrees, whatever)
+define bond {
+ line $3 by ($1) * sin(($2)/deg), ($1) * cos(($2)/deg)
+}
+
+# fancy bonds: r, theta, from/at
+define doublebond {
+ line $3 invis by ($1) * sin(($2)/deg), ($1) * cos(($2)/deg)
+ V1: last line.start; V2: last line.end; dx = V2.x-V1.x; dy = V2.y-V1.y
+ norm = sqrt(dx*dx + dy*dy)
+ ny = dx * .02 / norm
+ nx = -dy * .02 / norm
+ line from V1 + (nx,ny) to V2 + (nx,ny)
+ line from V1 - (nx,ny) to V2 - (nx,ny)
+ move to V2
+}
+define triplebond {
+ line $3 invis by ($1) * sin(($2)/deg), ($1) * cos(($2)/deg)
+ V1: last line.start; V2: last line.end; dx = V2.x-V1.x; dy = V2.y-V1.y
+ norm = sqrt(dx*dx + dy*dy)
+ ny = dx * .025 / norm
+ nx = -dy * .025 / norm
+ line from V1 + (nx,ny) to V2 + (nx,ny)
+ line from V1 - (nx,ny) to V2 - (nx,ny)
+ line from V1 to V2
+ move to V2
+}
+define backbond {
+ line $3 invis by ($1) * sin(($2)/deg), ($1) * cos(($2)/deg)
+ V1: last line.start; V2: last line.end; dx = V2.x-V1.x; dy = V2.y-V1.y
+ norm = sqrt(dx*dx + dy*dy)
+ n = norm / .025
+ ny = dx * .02 / norm
+ nx = -dy * .02 / norm
+ for i = 1 to n-1 do {
+ XZ: i/n <V1,V2>
+ line from XZ + (nx,ny) to XZ - (nx,ny)
+ }
+ move to V2
+}
+define frontbond {
+ line $3 invis by ($1) * sin(($2)/deg), ($1) * cos(($2)/deg)
+ V1: last line.start; V2: last line.end; dx = V2.x-V1.x; dy = V2.y-V1.y
+ ah = arrowht; aw = arrowwid; ahead = arrowhead
+ arrowht = sqrt(dx*dx + dy*dy)
+ arrowwid = 0.05
+ arrowhead = 7
+ line <- from V1 to V2
+ arrowht = ah; arrowwid = aw; arrowhead = ahead
+}
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
diff --git a/contrib/chem/chem.pl b/contrib/chem/chem.pl
new file mode 100755
index 00000000..dacf8b41
--- /dev/null
+++ b/contrib/chem/chem.pl
@@ -0,0 +1,1274 @@
+#! /usr/bin/env perl
+
+# chem - a groff preprocessor for producing chemical structure diagrams
+
+# Source file position: <groff-source>/contrib/chem/chem.pl
+# Installed position: <prefix>/bin/chem
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+########################################################################
+# settings
+########################################################################
+
+my $Program_Version = '0.3.1';
+my $Last_Update = '03 Jan 2009';
+
+# this setting of the groff version is only used before make is run,
+# otherwise @VERSION@ will set it.
+my $Groff_Version_Preset='1.20preset';
+
+# test on Perl version
+require v5.6;
+
+
+########################################################################
+# begin
+########################################################################
+
+use warnings;
+use strict;
+use Math::Trig;
+
+# for catfile()
+use File::Spec;
+
+# $Bin is the directory where this script is located
+use FindBin;
+
+my $Chem_Name;
+my $Groff_Version;
+my $File_chem_pic;
+my $File_pic_tmac;
+
+BEGIN {
+ {
+ my $before_make; # script before run of `make'
+ {
+ my $at = '@';
+ $before_make = 1 if '@VERSION@' eq "${at}VERSION${at}";
+ }
+
+ my %at_at;
+
+ if ($before_make) {
+ my $chem_dir = $FindBin::Bin;
+ $at_at{'BINDIR'} = $chem_dir;
+ $at_at{'G'} = '';
+ $File_chem_pic = File::Spec->catfile($chem_dir, 'chem.pic');
+ $File_pic_tmac = File::Spec->catfile($chem_dir, '..', 'pic.tmac');
+ $Groff_Version = '';
+ $Chem_Name = 'chem';
+ } else {
+ $Groff_Version = '@VERSION@';
+ $at_at{'BINDIR'} = '@BINDIR@';
+ $at_at{'G'} = '@g@';
+ $at_at{'PICDIR'} = '@PICDIR@';
+ $at_at{'TMACDIR'} = '@MACRODIR@';
+ $File_chem_pic =
+ File::Spec->catfile($at_at{'PICDIR'}, 'chem.pic');
+ $File_pic_tmac = File::Spec->catfile($at_at{'TMACDIR'}, 'pic.tmac');
+ $Chem_Name = $at_at{'G'} . 'chem';
+ }
+ }
+}
+
+
+########################################################################
+# check the parameters
+########################################################################
+
+if (@ARGV) {
+ # process any FOO=bar switches
+ # eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
+ my @filespec = ();
+ my $dbl_minus;
+ my $wrong;
+ foreach (@ARGV) {
+ next unless $_;
+ if (/=/) {
+ # ignore FOO=bar switches
+ push @filespec, $_ if -f;
+ next;
+ }
+ if ($dbl_minus) {
+ if (-f $_) {
+ push @filespec, $_ if -s $_;
+ } else {
+ warn "chem: argument $_ is not an existing file.\n";
+ $wrong = 1;
+ }
+ next;
+ }
+ if (/^--$/) {
+ $dbl_minus = 1;
+ next;
+ }
+ if (/^-$/) {
+ push @filespec, $_;
+ next;
+ }
+ if (/^-h$/ or '--help' =~ /^$_/) {
+ &usage();
+ exit 0;
+ }
+ if (/^-v$/ or '--version' =~ /^$_/) {
+ &version();
+ exit 0;
+ }
+ if (-f $_) {
+ push @filespec, $_ if -s $_;
+ } else {
+ $wrong = 1;
+ if (/^-/) {
+ warn "chem: wrong option ${_}.\n";
+ } else {
+ warn "chem: argument $_ is not an existing file.\n";
+ }
+ }
+ }
+ if (@filespec) {
+ @ARGV = @filespec;
+ } else {
+ exit 0 if $wrong;
+ @ARGV = ('-');
+ }
+} else { # @ARGV is empty
+ @ARGV = ('-') unless @ARGV;
+}
+
+
+########################################################################
+# main process
+########################################################################
+
+my %Dc = ( 'up' => 0, 'right' => 90, 'down' => 180, 'left' => 270,
+ 'ne' => 45, 'se' => 135, 'sw' => 225, 'nw' => 315,
+ 0 => 'n', 90 => 'e', 180 => 's', 270 => 'w',
+ 30 => 'ne', 45 => 'ne', 60 => 'ne',
+ 120 => 'se', 135 => 'se', 150 => 'se',
+ 210 => 'sw', 225 => 'sw', 240 => 'sw',
+ 300 => 'nw', 315 => 'nw', 330 => 'nw',
+ );
+
+my $Word_Count;
+my @Words;
+
+my $Line_No;
+my $Last_Name = '';
+
+# from init()
+my $First_Time = 1;
+my $Last_Type;
+my $Dir; # direction
+my %Types = (
+ 'RING' => 'R',
+ 'MOL' => 'M',
+ 'BOND' => 'B',
+ 'OTHER' => 'O' # manifests
+ );
+
+# from setparams()
+my %Params;
+
+# from ring()
+my $Nput;
+my $Aromatic;
+my %Put;
+my %Dbl;
+
+my %Labtype;
+my %Define = ();
+
+my $File_Name = '';
+my $Line = '';
+
+&main();
+
+{
+ my $is_pic = '';
+ my $is_chem = '';
+ my $former_line = '';
+
+ ##########
+ # main()
+ #
+ sub main {
+ my $count_minus = 0;
+ my @stdin = ();
+ my $stdin = 0;
+
+ # for centralizing the pic code
+ open TMAC, "<$File_pic_tmac" and print <TMAC>;
+ close TMAC;
+
+ foreach (@ARGV) {
+ $count_minus++ if /^-$/;
+ }
+
+ foreach my $arg (@ARGV) {
+ &setparams(1.0);
+ next unless $arg;
+ $Line_No = 0;
+ $is_pic = '';
+ $is_chem = '';
+ if ($arg eq '-') {
+ $File_Name = 'standard input';
+ if ($stdin) {
+ &main_line($_) foreach @stdin;
+ } else {
+ $stdin = 1;
+ if ($count_minus <= 1) {
+ while (<STDIN>) {
+ &main_line($_);
+ }
+ } else {
+ @stdin = ();
+ while (<STDIN>) {
+ push @stdin, $_;
+ &main_line($_);
+ }
+ }
+ }
+### main()
+ } else { # $arg is not -
+ $File_Name = $arg;
+ open FILE, "<$arg";
+ &main_line($_) while <FILE>;
+ close FILE;
+ } # if $arg
+ if ($is_pic) {
+ printf ".PE\n";
+ }
+ }
+ } # main()
+
+
+ ##########
+ # main_line()
+ #
+ sub main_line {
+ my $line = $_[0];
+# $Last_Type = $Types{'OTHER'};
+# $Last_Type = '';
+ my $stack;
+ $Line_No++;
+ chomp $line;
+
+ $line = $former_line . $line if $former_line;
+ if ($line =~ /^(.*)\\$/) {
+ $former_line = $1;
+ return 1;
+ } else {
+ $former_line = '';
+ }
+ $Line = $line;
+
+ {
+ @Words = ();
+ my $s = $line;
+ $s =~ s/^\s*//;
+ $s =~ s/\s+$//;
+ return 1 unless $s;
+ $s = " $s";
+ $s =~ s/\s+#.*$// if $is_pic;
+ return 1 unless $s;
+ $line = $s;
+ $line =~ s/^\s*|\s*$//g;
+ my $bool = 1;
+ while ($bool) {
+ $s =~ /^([^"]*)\s("[^"]*"?\S*)(.*)$/;
+ if (defined $1) {
+ my $s1 = $1;
+ my $s2 = $2;
+ $s = $3;
+ $s1 =~ s/^\s*|\s*$//g;
+ push @Words, split(/\s+/, $s1) if $s1;
+ push @Words, $s2;
+ }
+ if ($s !~ /\s"/) {
+ $s =~ s/^\s*|\s*$//g;
+ push @Words, split(/\s+/, $s) if $s;
+ $bool = 0;
+ }
+ }
+
+# @Words = split(/\s+/, $s);
+ return 1 unless @Words;
+# foreach my $i (0..$#Words) {
+# if ($Words[$i] =~ /^\s*#/) {
+# $#Words = $i - 1;
+# last;
+# }
+# }
+# return 1 unless @Words;
+ }
+
+ if ($line =~ /^([\.']\s*PS\s*)|([\.']\s*PS\s.+)$/) {
+ # .PS
+ unless ($is_pic) {
+ $is_pic = 'running';
+ print "$line\n";
+ }
+ return 1;
+ }
+### main_line()
+ if ( $line =~ /^([\.']\s*PE\s*)|([\.']\s*PE\s.+)$/ ) {
+ # .PE
+ $is_chem = '';
+ if ($is_pic) {
+ $is_pic = '';
+ print "$line\n";
+ }
+ return 1;
+ }
+ if ($line =~ /^[\.']\s*cstart\s*$/) {
+ # line: `.cstart'
+ if ($is_chem) {
+ &error("additional `.cstart'; chem is already active.");
+ return 1;
+ }
+ unless ($is_pic) {
+ &print_ps();
+ $is_pic = 'by chem';
+ }
+ $is_chem = '.cstart';
+ &init();
+ return 1;
+ }
+### main_line()
+ if ($line =~ /^\s*begin\s+chem\s*$/) {
+ # line: `begin chem'
+ if ($is_pic) {
+ if ($is_chem) {
+ &error("additional `begin chem'; chem is already active.");
+ return 1;
+ }
+ $is_chem = 'begin chem';
+ &init();
+ } else {
+ print "$line\n";
+ }
+ return 1;
+ }
+ if ($line =~ /^[\.']\s*cend\s*/) {
+ # line `.cend'
+ if ($is_chem) {
+ &error("you end chem with `.cend', but started it with `begin chem'.")
+ if $is_chem eq 'begin chem';
+ if ($is_pic eq 'by chem') {
+ &print_pe();
+ $is_pic = '';
+ }
+ $is_chem = '';
+ } else {
+ print "$line\n";
+ }
+ return 1;
+ }
+ if ($line =~ /^\s*end\s*$/) {
+ # line: `end'
+ if ($is_chem) {
+ &error("you end chem with `end', but started it with `.cstart'.")
+ if $is_chem eq '.cstart';
+ if ($is_pic eq 'by chem') {
+ &print_pe();
+ $is_pic = '';
+ }
+ $is_chem = '';
+ } else {
+ print "$line\n";
+ }
+ return 1;
+ }
+
+### main_line()
+ if (! $is_chem) {
+ print "$line\n";
+ return 1;
+ }
+ if ($line =~ /^[.']/) {
+ # groff request line
+ print "$line\n";
+ return 1;
+ }
+
+ if ($Words[0] eq 'pic') {
+ # pic pass-thru
+ return 1 if $#Words == 0;
+ my $s = $line;
+ $s =~ /^\s*pic\s*(.*)$/;
+ $s = $1;
+ print "$s\n" if $s;
+ $Last_Type = $Types{'OTHER'};
+ $Define{ $Words[2] } = 1 if $#Words >= 2 && $Words[1] eq 'define';
+ return 1;
+ }
+
+ if ($Words[0] eq 'textht') {
+ if ($#Words == 0) {
+ &error("`textht' needs a single argument.");
+ return 0;
+ }
+ &error("only the last argument is taken for `textht', " .
+ "all others are ignored.")
+ unless $#Words <= 1 or ($#Words == 2 && $Words[1] =~ /^=/);
+ $Params{'textht'} = $Words[$#Words];
+ return 1;
+ }
+### main_line()
+ if ($Words[0] eq 'cwid') { # character width
+ if ($#Words == 0) {
+ &error("`cwid' needs a single argument.");
+ return 0;
+ }
+ &error("only the last argument is taken for `cwid', " .
+ "all others are ignored.")
+ unless $#Words <= 1 or ($#Words == 2 && $Words[1] =~ /^=/);
+ $Params{'cwid'} = $Words[$#Words];
+ return 1;
+ }
+ if ($Words[0] eq 'db') { # bond length
+ if ($#Words == 0) {
+ &error("`db' needs a single argument.");
+ return 0;
+ }
+ &error("only the last argument is taken for `db', " .
+ "all others are ignored.")
+ unless $#Words <= 1 or ($#Words == 2 && $Words[1] =~ /^=/);
+ $Params{'db'} = $Words[$#Words];
+ return 1;
+ }
+ if ($Words[0] eq 'size') { # size for all parts of the whole diagram
+ my $size;
+ if ($#Words == 0) {
+ &error("`size' needs a single argument.");
+ return 0;
+ }
+ &error("only the last argument is taken for `size', " .
+ "all others are ignored.")
+ unless $#Words <= 1 or ($#Words == 2 && $Words[1] =~ /^=/);
+ if ($Words[$#Words] <= 4) {
+ $size = $Words[$#Words];
+ } else {
+ $size = $Words[$#Words] / 10;
+ }
+ &setparams($size);
+ return 1;
+ }
+
+### main_line()
+ print "\n#", $Line, "\n"; # debugging, etc.
+ $Last_Name = '';
+# $Last_Type = $Types{'OTHER'};
+# $Last_Type = '';
+
+ if ($Words[0] =~ /^[A-Z].*:$/) {
+ # label; falls thru after shifting left
+ my $w = $Words[0];
+ $Last_Name = $w;
+ $Last_Name =~ s/:$//;
+ print "$w";
+ shift @Words;
+ if (@Words) {
+ print " ";
+ $line =~ s/^\s*$w\s*//;
+ } else {
+ print "\n";
+ return 1;
+ }
+ }
+
+ if ($Words[0] eq 'define') {
+ print "$line\n";
+ $Define{ $Words[1] } = 1 if $#Words >= 1;
+ $Last_Type = $Types{'OTHER'};
+ return 1;
+ }
+ if ($Words[0] =~ /^[\[\]{}]/) {
+ print "$line\n";
+ $Last_Type = $Types{'OTHER'};
+ return 1;
+ }
+
+ if ($Words[0] =~ /^"/) {
+ print 'Last: ', $line, "\n";
+ $Last_Type = $Types{'OTHER'};
+ return 1;
+ }
+
+ if ($Words[0] =~ /bond/) {
+ &bond($Words[0]);
+ return 1;
+ }
+
+ if ($#Words >= 1) {
+ if ($Words[0] =~ /^(double|triple|front|back)$/ &&
+ $Words[1] eq 'bond') {
+ my $w = shift @Words;
+ $Words[0] = $w . $Words[0];
+ &bond($Words[0]);
+ return 1;
+ }
+ if ($Words[0] eq 'aromatic') {
+ my $temp = $Words[0];
+ $Words[0] = $Words[1] ? $Words[1] : '';
+ $Words[1] = $temp;
+ }
+ }
+
+ if ($Words[0] =~ /ring|benz/) {
+ &ring($Words[0]);
+ return 1;
+ }
+ if ($Words[0] eq 'methyl') {
+ # left here as an example
+ $Words[0] = 'CH3';
+ }
+### main_line()
+ if ($Words[0] =~ /^[A-Z]/) {
+ &molecule();
+ return 1;
+ }
+ if ($Words[0] eq 'left') {
+ my %left; # not used
+ $left{++$stack} = &fields(1, $#Words);
+ printf (("Last: [\n"));
+ return 1;
+ }
+ if ($Words[0] eq 'right') {
+ &bracket();
+ $stack--;
+ return 1;
+ }
+ if ($Words[0] eq 'label') { # prints the vertex numbers in a ring
+ if ( exists $Labtype{$Words[1]} and
+ $Labtype{$Words[1]} =~ /^$Types{'RING'}/ ) {
+ my $v = substr($Labtype{$Words[1]}, 1, 1);
+ $Words[1] = '' unless $Words[1];
+ foreach my $i ( 1..$v ) {
+ printf "\"\\s-3%d\\s0\" at 0.%d<%s.C,%s.V%d>\n", $i, $v + 2,
+ $Words[1], $Words[1], $i;
+ }
+ } else {
+ &error("$Words[1] is not a ring.");
+ }
+ return 1;
+ }
+
+ if ( exists $Define{ $Words[0] } ) {
+ print $line, "\n";
+ $Last_Type = $Types{'OTHER'};
+ return 1;
+ }
+ return 1 unless $line;
+# print STDERR "# $Line\n";
+# &error('This is not a chem command. To include a command for pic, ' .
+# "add `pic' as the first word to the command.");
+ print $line, "\n";
+ $Last_Type = $Types{'OTHER'};
+ 1;
+ } # main_line()
+
+}
+
+########################################################################
+# functions
+########################################################################
+
+##########
+# atom(<string>)
+#
+sub atom {
+ # convert CH3 to atom(...)
+ my ($s) = @_;
+ my ($i, $n, $nsub, $cloc, $nsubc, @s);
+ if ($s eq "\"\"") {
+ return $s;
+ }
+ $n = length($s);
+ $nsub = $nsubc = 0;
+ $cloc = index($s, 'C');
+ if (! defined($cloc) || $cloc < 0) {
+ $cloc = 0;
+ }
+ @s = split('', $s);
+ $i = 0;
+ foreach (@s) {
+ unless (/[A-Z]/) {
+ $nsub++;
+ $nsubc++ if $i < $cloc;
+ $i++;
+ }
+ }
+ $s =~ s/([0-9]+\.[0-9]+)|([0-9]+)/\\s-3\\d$&\\u\\s+3/g;
+ if ($s =~ /([^0-9]\.)|(\.[^0-9])/) { # centered dot
+ $s =~ s/\./\\v#-.3m#.\\v#.3m#/g;
+ }
+ sprintf( "atom(\"%s\", %g, %g, %g, %g, %g, %g)",
+ $s, ($n - $nsub / 2) * $Params{'cwid'}, $Params{'textht'},
+ ($cloc - $nsubc / 2 + 0.5) * $Params{'cwid'}, $Params{'crh'},
+ $Params{'crw'}, $Params{'dav'}
+ );
+} # atom()
+
+
+##########
+# bond(<type>)
+#
+sub bond {
+ my ($type) = @_;
+ my ($i, $moiety, $from, $leng);
+ $moiety = '';
+ for ($i = 1; $i <= $#Words; $i++) {
+ if ($Words[$i] eq ';') {
+ &error("a colon `;' must be followed by a space and a single word.")
+ if $i != $#Words - 1;
+ $moiety = $Words[$i + 1] if $#Words > $i;
+ $#Words = $i - 1;
+ last;
+ }
+ }
+ $leng = $Params{'db'}; # bond length
+ $from = '';
+ for ($Word_Count = 1; $Word_Count <= $#Words; ) {
+ if ($Words[$Word_Count] =~
+ /(\+|-)?\d+|up|down|right|left|ne|se|nw|sw/) {
+ $Dir = &cvtdir($Dir);
+ } elsif ($Words[$Word_Count] =~ /^leng/) {
+ $leng = $Words[$Word_Count + 1] if $#Words > $Word_Count;
+ $Word_Count += 2;
+ } elsif ($Words[$Word_Count] eq 'to') {
+ $leng = 0;
+ $from = &fields($Word_Count, $#Words);
+ last;
+ } elsif ($Words[$Word_Count] eq 'from') {
+ $from = &dofrom();
+ last;
+ } elsif ($Words[$Word_Count] =~ /^#/) {
+ $Word_Count = $#Words + 1;
+ last;
+ } else {
+ $from = &fields($Word_Count, $#Words);
+ last;
+ }
+ }
+### bond()
+ if ($from =~ /( to )|^to/) { # said "from ... to ...", so zap length
+ $leng = 0;
+ } elsif (! $from) { # no from given at all
+ $from = 'from Last.' . &leave($Last_Type, $Dir) . ' ' .
+ &fields($Word_Count, $#Words);
+ }
+ printf "Last: %s(%g, %g, %s)\n", $type, $leng, $Dir, $from;
+ $Last_Type = $Types{'BOND'};
+ $Labtype{$Last_Name} = $Last_Type if $Last_Name;
+ if ($moiety) {
+ @Words = ($moiety);
+ &molecule();
+ }
+} # bond()
+
+
+##########
+# bracket()
+#
+sub bracket {
+ my $t;
+ printf (("]\n"));
+ if ($Words[1] && $Words[1] eq ')') {
+ $t = 'spline';
+ } else {
+ $t = 'line';
+ }
+ printf "%s from last [].sw+(%g,0) to last [].sw to last [].nw to last " .
+ "[].nw+(%g,0)\n", $t, $Params{'dbrack'}, $Params{'dbrack'};
+ printf "%s from last [].se-(%g,0) to last [].se to last [].ne to last " .
+ "[].ne-(%g,0)\n", $t, $Params{'dbrack'}, $Params{'dbrack'};
+ if ($Words[2] && $Words[2] eq 'sub') {
+ printf "\" %s\" ljust at last [].se\n", &fields(3, $#Words);
+ }
+} # bracket()
+
+
+##########
+# corner(<dir>)
+#
+# Return the corner name next to the given angle.
+#
+sub corner {
+ my ($d) = @_;
+ $Dc{ (45 * int(($d + 22.5) / 45)) % 360 };
+} # corner()
+
+
+##########
+# cvtdir(<dir>)
+#
+# Maps "[pointing] somewhere" to degrees.
+#
+sub cvtdir {
+ my ($d) = @_;
+ if ($Words[$Word_Count] eq 'pointing') {
+ $Word_Count++;
+ }
+ if ($Words[$Word_Count] =~ /^[+\\-]?\d+/) {
+ return ( $Words[$Word_Count++] % 360 );
+ } elsif ($Words[$Word_Count] =~ /left|right|up|down|ne|nw|se|sw/) {
+ return ( $Dc{$Words[$Word_Count++]} % 360 );
+ } else {
+ $Word_Count++;
+ return $d;
+ }
+} # cvtdir()
+
+
+##########
+# dblring(<v>)
+#
+sub dblring {
+ my ($v) = @_;
+ my ($d, $v1, $v2);
+ # should canonicalize to i,i+1 mod v
+ $d = $Words[$Word_Count];
+ for ($Word_Count++; $Word_Count <= $#Words &&
+ $Words[$Word_Count] =~ /^[1-9]/; $Word_Count++) {
+ $v1 = substr($Words[$Word_Count], 0, 1);
+ $v2 = substr($Words[$Word_Count], 2, 1);
+ if ($v2 == $v1 + 1 || $v1 == $v && $v2 == 1) { # e.g., 2,3 or 5,1
+ $Dbl{$v1} = $d;
+ } elsif ($v1 == $v2 + 1 || $v2 == $v && $v1 == 1) { # e.g., 3,2 or 1,5
+ $Dbl{$v2} = $d;
+ } else {
+ &error(sprintf("weird %s bond in\n\t%s", $d, $_));
+ }
+ }
+} # dblring()
+
+
+##########
+# dofrom()
+#
+sub dofrom {
+ my $n;
+ $Word_Count++; # skip "from"
+ $n = $Words[$Word_Count];
+ if (defined $Labtype{$n}) { # "from Thing" => "from Thing.V.s"
+ return 'from ' . $n . '.' . &leave($Labtype{$n}, $Dir);
+ }
+ if ($n =~ /^\.[A-Z]/) { # "from .V" => "from Last.V.s"
+ return 'from Last' . $n . '.' . &corner($Dir);
+ }
+ if ($n =~ /^[A-Z][^.]*\.[A-Z][^.]*$/) { # "from X.V" => "from X.V.s"
+ return 'from ' . $n . '.' . &corner($Dir);
+ }
+ &fields($Word_Count - 1, $#Words);
+} # dofrom()
+
+
+##########
+# error(<string>)
+#
+sub error {
+ my ($s) = @_;
+ printf STDERR "chem: error in %s on line %d: %s\n",
+ $File_Name, $Line_No, $s;
+} # error()
+
+
+##########
+# fields(<n1>, <n2>)
+#
+sub fields {
+ my ($n1, $n2) = @_;
+ if ($n1 > $n2) {
+ return '';
+ }
+ my $s = '';
+ foreach my $i ($n1..$n2) {
+ if ($Words[$i] =~ /^#/) {
+ last;
+ }
+ $s = $s . $Words[$i] . ' ';
+ }
+ $s;
+} # fields()
+
+
+##########
+# init()
+#
+sub init {
+ if ($First_Time) {
+ printf "copy \"%s\"\n", $File_chem_pic;
+ printf "\ttextht = %g; textwid = .1; cwid = %g\n",
+ $Params{'textht'}, $Params{'cwid'};
+ printf "\tlineht = %g; linewid = %g\n",
+ $Params{'lineht'}, $Params{'linewid'};
+ $First_Time = 0;
+ }
+ printf "Last: 0,0\n";
+ $Last_Type = $Types{'OTHER'};
+ $Dir = 90;
+} # init()
+
+
+##########
+# leave(<last>, <d>)
+#
+sub leave {
+ my ($last, $d) = @_;
+ my ($c, $c1);
+ # return vertex of $last in direction $d
+ if ( $last eq $Types{'BOND'} ) {
+ return 'end';
+ }
+ $d %= 360;
+ if ( $last =~ /^$Types{'RING'}/ ) {
+ return &ringleave($last, $d);
+ }
+ if ( $last eq $Types{'MOL'} ) {
+ if ($d == 0 || $d == 180) {
+ $c = 'C';
+ } elsif ($d > 0 && $d < 180) {
+ $c = 'R';
+ } else {
+ $c = 'L';
+ }
+ if (defined $Dc{$d}) {
+ $c1 = $Dc{$d};
+ } else {
+ $c1 = &corner($d);
+ }
+ return sprintf('%s.%s', $c, $c1);
+ }
+ if ( $last eq $Types{'OTHER'} ) {
+ return &corner($d);
+ }
+ 'c';
+} # leave()
+
+
+##########
+# makering(<type>, <pt>, <v>)
+#
+sub makering {
+ my ($type, $pt, $v) = @_;
+ my ($i, $j, $a, $r, $rat, $fix, $c1, $c2);
+ if ($type =~ /flat/) {
+ $v = 6;
+ # vertices
+ ;
+ }
+ $r = $Params{'ringside'} / (2 * sin(pi / $v));
+ printf "\tC: 0,0\n";
+ for ($i = 0; $i <= $v + 1; $i++) {
+ $a = (($i - 1) / $v * 360 + $pt) / 57.29578; # 57. is $deg
+ printf "\tV%d: (%g,%g)\n", $i, $r * sin($a), $r * cos($a);
+ }
+ if ($type =~ /flat/) {
+ printf "\tV4: V5; V5: V6\n";
+ $v = 5;
+ }
+ # sides
+ if ($Nput > 0) {
+ # hetero ...
+ for ($i = 1; $i <= $v; $i++) {
+ $c1 = $c2 = 0;
+ if ($Put{$i} ne '') {
+ printf "\tV%d: ellipse invis ht %g wid %g at V%d\n",
+ $i, $Params{'crh'}, $Params{'crw'}, $i;
+ printf "\t%s at V%d\n", $Put{$i}, $i;
+ $c1 = $Params{'cr'};
+ }
+ $j = $i + 1;
+ if ($j > $v) {
+ $j = 1;
+ }
+### makering()
+ if ($Put{$j} ne '') {
+ $c2 = $Params{'cr'};
+ }
+ printf "\tline from V%d to V%d chop %g chop %g\n", $i, $j, $c1, $c2;
+ if ($Dbl{$i} ne '') {
+ # should check i<j
+ if ($type =~ /flat/ && $i == 3) {
+ $rat = 0.75;
+ $fix = 5;
+ } else {
+ $rat = 0.85;
+ $fix = 1.5;
+ }
+ if ($Put{$i} eq '') {
+ $c1 = 0;
+ } else {
+ $c1 = $Params{'cr'} / $fix;
+ }
+ if ($Put{$j} eq '') {
+ $c2 = 0;
+ } else {
+ $c2 = $Params{'cr'} / $fix;
+ }
+ printf "\tline from %g<C,V%d> to %g<C,V%d> chop %g chop %g\n",
+ $rat, $i, $rat, $j, $c1, $c2;
+ if ($Dbl{$i} eq 'triple') {
+ printf "\tline from %g<C,V%d> to %g<C,V%d> chop %g chop %g\n",
+ 2 - $rat, $i, 2 - $rat, $j, $c1, $c2;
+ }
+ }
+ }
+### makering()
+ } else {
+ # regular
+ for ($i = 1; $i <= $v; $i++) {
+ $j = $i + 1;
+ if ($j > $v) {
+ $j = 1;
+ }
+ printf "\tline from V%d to V%d\n", $i, $j;
+ if ($Dbl{$i} ne '') {
+ # should check i<j
+ if ($type =~ /flat/ && $i == 3) {
+ $rat = 0.75;
+ } else {
+ $rat = 0.85;
+ }
+ printf "\tline from %g<C,V%d> to %g<C,V%d>\n",
+ $rat, $i, $rat, $j;
+ if ($Dbl{$i} eq 'triple') {
+ printf "\tline from %g<C,V%d> to %g<C,V%d>\n",
+ 2 - $rat, $i, 2 - $rat, $j;
+ }
+ }
+ }
+ }
+### makering()
+ # punt on triple temporarily
+ # circle
+ if ($type =~ /benz/ || $Aromatic > 0) {
+ if ($type =~ /flat/) {
+ $r *= .4;
+ } else {
+ $r *= .5;
+ }
+ printf "\tcircle rad %g at 0,0\n", $r;
+ }
+} # makering()
+
+
+##########
+# molecule()
+#
+sub molecule {
+ my ($n, $type);
+ if ($#Words >= 0) {
+ $n = $Words[0];
+ if ($n eq 'BP') {
+ $Words[0] = "\"\" ht 0 wid 0";
+ $type = $Types{'OTHER'};
+ } else {
+ $Words[0] = &atom($n);
+ $type = $Types{'MOL'};
+ }
+ }
+ $n =~ s/[^A-Za-z0-9]//g; # for stuff like C(OH3): zap non-alnum
+ if ($#Words < 1) {
+ printf "Last: %s: %s with .%s at Last.%s\n",
+ $n, join(' ', @Words), &leave($type, $Dir + 180),
+ &leave($Last_Type, $Dir);
+### molecule()
+ } else {
+ if (! $Words[1]) {
+ printf "Last: %s: %s with .%s at Last.%s\n",
+ $n, join(' ', @Words), &leave($type, $Dir + 180),
+ &leave($Last_Type, $Dir);
+ } elsif ($#Words >= 1 and $Words[1] eq 'below') {
+ $Words[2] = '' if ! $Words[2];
+ printf "Last: %s: %s with .n at %s.s\n", $n, $Words[0], $Words[2];
+ } elsif ($#Words >= 1 and $Words[1] eq 'above') {
+ $Words[2] = '' if ! $Words[2];
+ printf "Last: %s: %s with .s at %s.n\n", $n, $Words[0], $Words[2];
+ } elsif ($#Words >= 2 and $Words[1] eq 'left' && $Words[2] eq 'of') {
+ $Words[3] = '' if ! $Words[3];
+ printf "Last: %s: %s with .e at %s.w+(%g,0)\n",
+ $n, $Words[0], $Words[3], $Params{'dew'};
+ } elsif ($#Words >= 2 and $Words[1] eq 'right' && $Words[2] eq 'of') {
+ $Words[3] = '' if ! $Words[3];
+ printf "Last: %s: %s with .w at %s.e-(%g,0)\n",
+ $n, $Words[0], $Words[3], $Params{'dew'};
+ } else {
+ printf "Last: %s: %s\n", $n, join(' ', @Words);
+ }
+ }
+
+ $Last_Type = $type;
+ if ($Last_Name) {
+ # $Last_Type = '';
+ $Labtype{$Last_Name} = $Last_Type;
+ }
+ $Labtype{$n} = $Last_Type;
+} # molecule()
+
+
+##########
+# print_hash(<hash_or_ref>)
+#
+# print the elements of a hash or hash reference
+#
+sub print_hash {
+ my $hr;
+ my $n = scalar @_;
+ if ($n == 0) {
+ print STDERR "empty hash\n;";
+ return 1;
+ } elsif ($n == 1) {
+ if (ref($_[0]) eq 'HASH') {
+ $hr = $_[0];
+ } else {
+ warn 'print_hash(): the argument is not a hash or hash reference;';
+ return 0;
+ }
+ } else {
+ if ($n % 2) {
+ warn 'print_hash(): the arguments are not a hash;';
+ return 0;
+ } else {
+ my %h = @_;
+ $hr = \%h;
+ }
+ }
+
+### print_hash()
+ unless (%$hr) {
+ print STDERR "empty hash\n";
+ return 1;
+ }
+ print STDERR "hash (ignore the ^ characters):\n";
+ for my $k (sort keys %$hr) {
+ my $hk = $hr->{$k};
+ print STDERR " $k => ";
+ if (defined $hk) {
+ print STDERR "^$hk^";
+ } else {
+ print STDERR "undef";
+ }
+ print STDERR "\n";
+ }
+
+ 1;
+} # print_hash()
+
+
+##########
+# print_pe()
+#
+sub print_pe {
+ print ".PE\n";
+} # print_pe()
+
+
+##########
+# print_ps()
+#
+sub print_ps {
+ print ".PS\n";
+} # print_ps()
+
+##########
+# putring(<v>)
+#
+sub putring {
+ # collect "put Mol at n"
+ my ($v) = @_;
+ my ($m, $mol, $n);
+ $Word_Count++;
+ $mol = $Words[$Word_Count++];
+ if ($Words[$Word_Count] eq 'at') {
+ $Word_Count++;
+ }
+ $n = $Words[$Word_Count];
+ if ($n !~ /^\d+$/) {
+ $n =~ s/(\d)+$/$1/;
+ $n = 0 if $n !~ /^\d+$/;
+ error('use single digit as argument for "put at"');
+ }
+ if ($n >= 1 && $n <= $v) {
+ $m = $mol;
+ $m =~ s/[^A-Za-z0-9]//g;
+ $Put{$n} = $m . ':' . &atom($mol);
+ } elsif ($n == 0) {
+ error('argument of "put at" must be a single digit');
+ } else {
+ error('argument of "put at" is too large');
+ }
+ $Word_Count++;
+} # putring()
+
+
+##########
+# ring(<type>)
+#
+sub ring {
+ my ($type) = @_;
+ my ($typeint, $pt, $verts, $i, $other, $fused, $withat);
+ $pt = 0; # points up by default
+ if ($type =~ /([1-8])$/) {
+ $verts = $1;
+ } elsif ($type =~ /flat/) {
+ $verts = 5;
+ } else {
+ $verts = 6;
+ }
+ $fused = $other = '';
+ for ($i = 1; $i <= $verts; $i++) {
+ $Put{$i} = $Dbl{$i} = '';
+ }
+ $Nput = $Aromatic = $withat = 0;
+ for ($Word_Count = 1; $Word_Count <= $#Words; ) {
+ if ($Words[$Word_Count] eq 'pointing') {
+ $pt = &cvtdir(0);
+ } elsif ($Words[$Word_Count] eq 'double' ||
+ $Words[$Word_Count] eq 'triple') {
+ &dblring($verts);
+ } elsif ($Words[$Word_Count] =~ /arom/) {
+ $Aromatic++;
+ $Word_Count++; # handled later
+### ring()
+ } elsif ($Words[$Word_Count] eq 'put') {
+ &putring($verts);
+ $Nput++;
+ } elsif ($Words[$Word_Count] =~ /^#/) {
+ $Word_Count = $#Words + 1;
+ last;
+ } else {
+ if ($Words[$Word_Count] eq 'with' || $Words[$Word_Count] eq 'at') {
+ $withat = 1;
+ }
+ $other = $other . ' ' . $Words[$Word_Count];
+ $Word_Count++;
+ }
+ }
+ $typeint = $Types{'RING'} . $verts . $pt; # RING | verts | dir
+ if ($withat == 0) {
+ # join a ring to something
+ if ( $Last_Type =~ /^$Types{'RING'}/ ) {
+ # ring to ring
+ if (substr($typeint, 2) eq substr($Last_Type, 2)) {
+ # fails if not 6-sided
+ $fused = 'with .V6 at Last.V2';
+ }
+ }
+ # if all else fails
+ $fused = sprintf('with .%s at Last.%s',
+ &leave($typeint, $Dir + 180), &leave($Last_Type, $Dir));
+ }
+ printf "Last: [\n";
+ &makering($type, $pt, $verts);
+ printf "] %s %s\n", $fused, $other;
+ $Last_Type = $typeint;
+ $Labtype{$Last_Name} = $Last_Type if $Last_Name;
+} # ring()
+
+
+##########
+# ringleave(<last>, <d>)
+#
+sub ringleave {
+ my ($last, $d) = @_;
+ my ($rd, $verts);
+ # return vertex of ring in direction d
+ $verts = substr($last, 1, 1);
+ $rd = substr($last, 2);
+ sprintf('V%d.%s', int( (($d - $rd) % 360) / (360 / $verts)) + 1,
+ &corner($d));
+} # ringleave()
+
+
+##########
+# setparams(<scale>)
+#
+sub setparams {
+ my ($scale) = @_;
+ $Params{'lineht'} = $scale * 0.2;
+ $Params{'linewid'} = $scale * 0.2;
+ $Params{'textht'} = $scale * 0.16;
+ $Params{'db'} = $scale * 0.2; # bond length
+ $Params{'cwid'} = $scale * 0.12; # character width
+ $Params{'cr'} = $scale * 0.08; # rad of invis circles at ring vertices
+ $Params{'crh'} = $scale * 0.16; # ht of invis ellipse at ring vertices
+ $Params{'crw'} = $scale * 0.12; # wid
+ $Params{'dav'} = $scale * 0.015; # vertical shift up for atoms in atom macro
+ $Params{'dew'} = $scale * 0.02; # east-west shift for left of/right of
+ $Params{'ringside'} = $scale * 0.3; # side of all rings
+ $Params{'dbrack'} = $scale * 0.1; # length of bottom of bracket
+} # setparams()
+
+
+##########
+# usage()
+#
+# Print usage information for --help.
+#
+sub usage {
+ print "\n";
+ &version();
+ print <<EOF;
+
+Usage: $Chem_Name [option]... [filespec]...
+
+$Chem_Name is a groff preprocessor for producing chemical structure
+diagrams. The output suits to the pic preprocessor.
+
+"filespec" is one of
+ "filename" name of a readable file
+ "-" for standard input
+
+All available options are
+
+-h --help print this usage message.
+-v --version print version information.
+
+EOF
+} # usage()
+
+
+##########
+# version()
+#
+# Get version information from version.sh and print a text with this.
+#
+sub version {
+ $Groff_Version = $Groff_Version_Preset unless $Groff_Version;
+ my $year = $Last_Update;
+ $year =~ s/^.* //;
+ print <<EOF;
+$Chem_Name $Program_Version of $Last_Update (Perl version)
+is part of groff version $Groff_Version.
+Copyright (C) $year Free Software Foundation, Inc.
+GNU groff and chem come with ABSOLUTELY NO WARRANTY.
+You may redistribute copies of groff and its subprograms
+under the terms of the GNU General Public License.
+EOF
+} # version()
+
+1;
+### Emacs settings
+# Local Variables:
+# mode: CPerl
+# End:
diff --git a/contrib/chem/examples/README.txt b/contrib/chem/examples/README.txt
new file mode 100644
index 00000000..da891b87
--- /dev/null
+++ b/contrib/chem/examples/README.txt
@@ -0,0 +1,65 @@
+This directory contains examples for the `chem' language.
+
+You can view the graphical display of the examples by calling
+
+ groffer <file>
+
+`groffer' calls `chem' automatically.
+
+If you want to transform example files to a different format use the
+`roff2*' programs:
+
+`roff2dvi' prints dvi format to standard output,
+`roff2html' generates html output,
+`roff2pdf' outputs pdf mode,
+`roff2ps' produces PostScript output,
+`roff2text' generates text output in the groff device `latin1',
+`roff2x' prints the output in the groff device X that is
+ suitable for programs like `gxditview' or `xditview'.
+
+To get a suitable `groff' output run
+
+ @g@chem <file> | groff -p ...
+
+On the displays, you can see rings consisting of several lines and
+bonds (lines). All points on rings and bonds that do not have a
+notation mean a C atom (carbon) filled with H atoms (hydrogen) such
+that the valence of 4 is satisfied.
+
+For example, suppose you have just a single line without any
+characters. That means a bond. It has two points, one at each end of
+the line. So each of these points stands for a C atom, the bond
+itself connects these 2 C atoms. To fulfill the valence of 4, each
+points has to carry additionally 3 H atoms. So the single empty bond
+stands for CH3-CH3, though this combination doesn't make much sense
+chemically.
+
+
+####### License
+
+Last update: 5 Jan 2009
+
+Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+This file is part of `chem', which is part of `groff'.
+
+`groff' 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.
+
+`groff' 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/>.
+
+
+####### Emacs settings
+
+Local Variables:
+mode: text
+End:
diff --git a/contrib/chem/examples/atp.chem b/contrib/chem/examples/atp.chem
new file mode 100644
index 00000000..076f961e
--- /dev/null
+++ b/contrib/chem/examples/atp.chem
@@ -0,0 +1,63 @@
+atp.chem:
+.cstart
+
+# Example file for `chem':
+# ATP or C10_H16_N5_O13_P3 or
+# [[[5-(6-aminopurin-9-yl)-3,4-dihydroxy-oxolan-2-yl]methoxy-hydroxy-
+# phosphoryl]oxy-hydroxy-phosphoryl]oxyphosphonic acid
+
+# Found at http://www.chemindustry.com/apps/chemicals.
+
+# Source file position: <groff-source>/contrib/chem/example/atp.chem
+# Installed position: <prefix>/share/doc/groff/example/chem/atp.chem
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 5 Jan 2009
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+R1: ring5 pointing left double 1,2 3,4 put N at 2 put N at 5
+B: benzene put N at 2 with .V6 at R1.V3 with .V5 at R1.V4
+ bond up ; NH2
+ backbond 170 length .7 from R1.V5
+R2: ring5 pointing down with .V2 put O at 1
+ bond down at R2.V2 ; H
+ bond down length .1 at R2.V3 ; H
+ bond up length .1 at R2.V3 ; OH
+ bond down length .1 at R2.V4 ; H
+ bond up length .1 at R2.V4 ; OH
+ frontbond 70 at R2.V5
+ bond 110 ; O
+ bond right ; P
+ doublebond up ; O
+ bond down from P ; OH
+ bond right from P ; O
+ bond right ; P
+ doublebond up ; O
+ bond down from P ; OH
+ bond right from P ; O
+ bond right ; P
+ doublebond up ; O
+ bond down from P ; OH
+ bond right from P ; OH
+
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/cholesterin.chem b/contrib/chem/examples/cholesterin.chem
new file mode 100644
index 00000000..d8684a1f
--- /dev/null
+++ b/contrib/chem/examples/cholesterin.chem
@@ -0,0 +1,52 @@
+cholesterin.chem:
+.cstart
+
+# Example file for `chem':
+# Cholesterin or C27_H46O or
+# 10,13-dimethyl-17-(6-methylheptan-2-yl)-2,3,4,5,6,9,11,12,14,15,16,17-
+# dodecahydro-1H-cyclopenta[a]phenanthren-3-ol
+
+# Source file position: <groff-source>/contrib/chem/example/cholesterin.p
+# Installed position: <prefix>/share/doc/groff/example/chem/cholesterin.p
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 5 Jan 2009
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+R1: ring6
+ bond -120 ; HO
+R2: ring6 with .V5 at R1.V3 with .V6 at R1.V2 double 4,5
+ bond up at R2.V6
+R3: ring6 with .V5 at R2.V1 with .V4 at R2.V2
+R4: flatring5 pointing up with .V4 at R3.V3 with .V5 at R3.V2
+ bond up at R4.V5
+ bond up at R4.V1
+B1: bond -60
+ bond 60 at B1.start
+ bond 120
+ bond 60
+ bond 120
+B2: bond 60
+ bond down at B2.start
+
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/ethamivan.chem b/contrib/chem/examples/ethamivan.chem
new file mode 100644
index 00000000..19c720cf
--- /dev/null
+++ b/contrib/chem/examples/ethamivan.chem
@@ -0,0 +1,48 @@
+ethamivan.chem:
+.cstart
+
+# Example file for `chem':
+# Ethamivan or Analepticon or C12_H17_N_O3 or
+# N,N-diethyl-4-hydroxy-3-methoxy-benzamide
+
+# Source file position: <groff-source>/contrib/chem/example/ethamivan.chem
+# Installed position: <prefix>/share/doc/groff/example/chem/ethamivan.chem
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 5 Jan 2009
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+R: ring pointing left double 2,3 4,5 6,1
+ bond left from R.V1 ; O
+ bond left ; H
+ bond -150 from R.V6 ; O
+ bond left
+ bond 60 from R.V4
+B1: double bond up ; O
+ bond 120 from B1.start ; N
+ bond 45
+ bond right
+ bond 135 from N
+ bond right
+
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/lsd.chem b/contrib/chem/examples/lsd.chem
new file mode 100644
index 00000000..f0b7407f
--- /dev/null
+++ b/contrib/chem/examples/lsd.chem
@@ -0,0 +1,51 @@
+lsd.chem:
+.cstart
+
+# Example file for `chem':
+# LSD or Lysergic acid dethylamide or C20_H25_N3O or
+# 9,10-Didehydro-N,N-diethyl-6-methyl-ergoline-8-beta-carboxamide
+
+# Source file position: <groff-source>/contrib/chem/example/lsd.p
+# Installed position: <prefix>/share/doc/groff/example/chem/lsd.p
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 5 Jan 2009
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+F: flatring5 pointing left put N at 5 double 3,4
+ H below F.N
+B: benzene pointing right with .V1 at F.V2
+R1: ring pointing right with .V4 at B.V6
+ front bond right from R1.V6 ; H
+R2: ring pointing right with .V2 at R1.V6 put N at 1 double 3,4
+ bond right from R2.N
+ back bond -60 from R2.V5 ; H
+ bond up from R2.V5
+B1: double bond up ; O
+ bond right from B1.start ; N
+ bond 45
+ bond right
+ bond 135 from N
+ bond right
+
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/morphine.chem b/contrib/chem/examples/morphine.chem
new file mode 100644
index 00000000..eefc68a4
--- /dev/null
+++ b/contrib/chem/examples/morphine.chem
@@ -0,0 +1,55 @@
+morphine.chem:
+.cstart
+
+# Example file for `chem':
+# Morphine or C23_H31_N3O or
+# N,N-diethyl-N'-(2-methoxyacridin-9-yl)-pentane-1,4-diamine
+
+# Found at http://www.chemindustry.com/apps/chemicals.
+
+# Source file position: <groff-source>/contrib/chem/example/morphine.chem
+# Installed position: <prefix>/share/doc/groff/example/chem/morphine.chem
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 5 Jan 2009
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+R1: benzene
+R2: benzene with .V6 at R1.V2 with .V5 at R1.V3 put N at 4
+R3: benzene with .V6 at R2.V2 with .V5 at R2.V3
+ bond 60 at R3.V2 ; O
+ bond 120
+ bond up at R2.V1 ; N
+ bond 60 ; H
+ bond -60 at N
+B1: backbond -120
+ bond up at B1.start
+ bond -60
+ bond up
+ bond -60 ; N
+ bond up
+ bond -60
+ bond -120 at N
+ bond -60
+
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/penicillin.chem b/contrib/chem/examples/penicillin.chem
new file mode 100644
index 00000000..99ac21d0
--- /dev/null
+++ b/contrib/chem/examples/penicillin.chem
@@ -0,0 +1,56 @@
+penicillin.chem:
+.cstart
+
+# Example file for `chem':
+# Penicillin or C16_H18_N2_O4_S or
+# 3,3-dimethyl-6-oxo-7-(2-phenylacetyl)amino-2-thia-5-
+# azabicyclo[3.2.0]heptane-4-carboxylic acid
+
+# Found at http://www.chemindustry.com/apps/chemicals.
+
+# Source file position: <groff-source>/contrib/chem/example/morphine.chem
+# Installed position: <prefix>/share/doc/groff/example/chem/morphine.chem
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 5 Jan 2009
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+R1: flatring5 pointing up put S at 1 put N at 4
+ bond 45 at R1.V2
+ bond 135 at R1.V2
+ bond 120 at R1.V3
+D1: doublebond 45 ; O
+ bond 135 at D1.start ; OH
+ bond left at R1.N
+ doublebond -135 ; O
+ bond left at R1.V5
+B1: bond down length .3
+ bond -60 at B1.start ; N
+ bond up ; H
+ bond -120 at N
+D2: doublebond down ; O
+ bond -60 at D2.start
+ bond -120
+ benzene
+
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/reserpine.chem b/contrib/chem/examples/reserpine.chem
new file mode 100644
index 00000000..05cd2c97
--- /dev/null
+++ b/contrib/chem/examples/reserpine.chem
@@ -0,0 +1,65 @@
+reserpine.chem:
+.PS
+begin chem
+
+# Example file for `chem':
+# Reserpine or C33H40N2O9
+
+# Source file position: <groff-source>/contrib/chem/example/reserpine.chem
+# Installed position: <prefix>/share/doc/groff/example/chem/reserpine.chem
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 5 Jan 2009
+
+# This file is part of `chem', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+R1: benzene pointing up
+ bond -120 from R1.V5 ; O
+ bond left
+R2: flatring5 pointing down double 4,5 with .V2 at R1.V3 with .V3 at R1.V2 put N at 1
+ H below R2.V1
+R3: ring put N at 3 with .V5 at R2.V5
+R4: ring put N at 1 with .V1 at R3.V3
+ back bond -120 from R4.V4 ; H
+ back bond 60 from R4.V3 ; H
+R5: ring with .V1 at R4.V3
+ bond -120
+D1: double bond down ; O
+ bond left from D1.start ; O
+ bond left
+ back bond 60 from R5.V3 ; H
+ back bond down from R5.V4 ; O
+ bond down from O
+ bond 120 from R5.V3 ; O
+ bond 50 from O
+D2: double bond up ; O
+ bond right length .1 from D2.start
+B: benzene pointing right
+ bond 45 from B.V6 ; O
+ bond right
+ bond right from B.V1 ; O
+ bond right
+ bond 135 from B.V2 ; O
+ bond right
+
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+end
+.PE
diff --git a/contrib/groffer/ChangeLog b/contrib/groffer/ChangeLog
new file mode 100644
index 00000000..2fc3d0f7
--- /dev/null
+++ b/contrib/groffer/ChangeLog
@@ -0,0 +1,314 @@
+2013-04-11 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * contrib/groffer: There is now a free `git' package containing
+ all old `groffer' versions `v0.*' and `v1.*'. The new versions
+ `groffer 2.*' will actually not be included. This package can be
+ got at:
+
+ $ git clone git@github.com:RUNOFF/groffer.git
+
+2013-03-29 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * perl/groffer.pl: Change viewers for `PS'.
+
+2013-03-29 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ * perl/groffer.pl: Change viewers for `PS' and `PDF'.
+
+ * version.sh: New version is `1.1.3'.
+
+2012-08-09 Werner LEMBERG <wl@gnu.org>
+
+ Synchronize man pages.
+
+ * perl/groffer.man, shell/groffer.man: Fix many minor issues.
+
+2012-08-07 Eric S. Raymond <esr@thyrsus.com>
+
+ Yet more elimination of low-level troff hackery in the
+ documentation so it can be lifted to structural markup.
+
+ * perl/groffer.man: Use .IP rather than .TP in
+ .Topic; this make structural parsing work. Also remove a
+ pointless and somewhat out-of-date .ig section.
+
+2011-10-17 Ingo Schwarze <schwarze@openbsd.org>
+
+ Do not use INSTALL_DATA and INSTALL_SCRIPT during build phase.
+
+ * Makefile.sub (groffer): Replace INSTALL_DATA and
+ INSTALL_SCRIPT with `cp'. Otherwise the build phase might
+ fail with `permission denied' if you use the `-o root' flag
+ of the `install' command. The use of INSTALL_* is an abuse
+ anyway because it's not installing anything at that point;
+ it's just copying files around locally, within in the build
+ directories.
+
+2011-03-21 Jan Vcelak <jvcelak@redhat.com>
+ Bernd Warken <groff-bernd.warken-72@web.de>
+
+ Remove hardcoded path to 'libdir/groff/groffer' directory.
+
+ * Makefile.sub: use @groffer_dir@
+
+ * groffer.pl: use @groffer_dir@
+
+2011-01-27 James Budiono <james.budiono@gmail.com>
+ Bernd Warken <groff-bernd.warken-72@web.de>
+
+ Fix display of manpages.
+
+ Reported as
+ http://lists.gnu.org/archive/html/bug-groff/2011-01/msg00015.html.
+
+ * perl/groffer.pl (_get_first_prog): Fix return value.
+ (Viewer_X): Add `okular' viewer.
+ * perl/man.pl (manpath_set_from_path): Handle `@main::Path)'
+ correctly.
+
+ * version.sh: Updated.
+
+2009-01-03 Werner LEMBERG <wl@gnu.org>
+
+ * version.sh: Prepare for groff release 1.20.
+
+2008-01-04 Werner LEMBERG <wl@gnu.org>
+
+ * shell/groffer.man, perl/groffer.man: Insert `\:' in URLs where
+ appropriate.
+
+2007-02-15 Eric S. Raymond <esr@snark.thyrsus.com>
+
+ * perl/groffer.man, perl/groffer.man: Fix non-portable `if'
+ expressions.
+
+2007-02-13 Eric S. Raymond <esr@snark.thyrsus.com>
+
+ Use an-ext.tmac macros in groffer.man.
+
+ * perl/groffer.man, perl/groffer.man: Replace ShellCommand with
+ .EX/.EE pairs.
+ Don't use .TP for examples, as some viewers won't handle a display
+ macro as a tag line. Use .SY/.OP/.YS rather than elaborate custom
+ macros.
+
+2007-02-02 Werner LEMBERG <wl@gnu.org>
+
+ * roff2.man: Further refinements and normalizations.
+
+2007-02-02 Eric S. Raymond <esr@snark.thyrsus.com>
+
+ * roff2.man: Converted to use .SY/.OP/.YS and for cross-viewer
+ portability. Conversion checked using the protocol described in
+ tmac/TESTING-HINTS.
+
+2006-11-14 Werner LEMBERG <wl@gnu.org>
+
+ * Makefile.sub (GROFFER_REST): Add roff2.man.
+ (groffer): Use $(INSTALL_DATA) for man pages.
+ Don't call `chmod' for $(ROFF2PROGS).
+ (roff2.man): Typographical fixes.
+
+2006-11-11 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of groffer 1.1.1
+
+ * perl/roff2.pl, shell/roff2.sh: Create a new working mode without
+ `groffer' for `roff2*'.
+
+ * perl/groffer.pl: Fix test of temporary directory.
+
+2006-11-09 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of groffer 1.1.0
+
+ * perl/groffer.pl, perl/func.pl, perl/groffer.man, \
+ shell/groffer2.sh, shell/groffer.man: Add `--debug-grog' to
+ display the `grog' output.
+
+ * perl/roff2.pl, shell/roff2.sh: New files for creating the roff2*
+ programs to transform roff code to different formats.
+
+ * roff2.man: New file to create man pages for the roff2*
+ programs.
+
+ * Makefile.sub: Add roff2* and some minor fixes.
+
+2006-11-04 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of groffer 1.0.3
+
+ * Makefile.sub:
+ - Delete removing of $(CLEANADD) in `groffer'.
+ - Add $(MAN1) to `groffer'.
+
+ * perl/groffer.pl, perl/func.pl, shell/groffer2.sh:
+ - Add `groff' option with argument `-K'.
+ - Redesign the changed `grog'.
+
+2006-10-23 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of groffer 1.0.2
+
+ * perl/groffer.pl:
+ - Move all variable declarations out of BEGIN.
+ - Move all `use' commands outside of BEGIN. Fix the arising
+ errors.
+ - Correct new position of perl/perl_test.pl.
+
+ * perl/func.pl:
+ - version(): Fix the determination of the version of groff.
+ - usage(): Sort it among the functions in this file.
+
+ * perl/groffer.man, shell/groffer.man: Fix string variable
+ Ellipsis.
+
+ * shell/README_SH: Add information on Autobook.
+
+ * shell/groffer.sh:
+ - Extent simple shell tests by testing on support for functions.
+ Test standard shell on function support. Add error reports on
+ shell tests.
+ - Set unset variables LANG LC_ALL LC_MESSAGES LC_CTYPES LANGUAGES
+ to `C', according to Autobook, ch. 22.
+ - Remove option `-e' from `sed'.
+
+ * shell/groffer2.sh:
+ - Add test on directory in man path find.
+ - Add Bourne compatibility for zsh shell.
+ - Replace `echo -n ""' by `:'.
+ - Remove -e option from sed.
+
+2006-10-23 Werner Lemberg
+
+ * perl_test.pl: Moved to...
+ * perl/perl_test.pl: Here.
+
+ * Makefile.sub: Rewritten. Change PERL to HAVE_PERL and SHELL to
+ HAVE_SHELL.
+
+2006-10-14 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of groffer 1.0.1
+
+ * perl/groffer.pl: Change $perl_test_pl to $file_perl_test_pl.
+
+ * perl/groffer.pl, perl/func.pl: Remove `\n' in `die' calls.
+
+2006-10-12 Bernd Warken <groff-bernd.warken-72@web.de>
+ ________________________________________________________________
+ * release of groffer 1.0.0
+
+ Changements of the shell version since 0.9.31
+
+ * shell/groffer.sh: Use version.sh in the upper directory.
+
+2006-10-02 Bernd Warken <groff-bernd.warken-72@web.de>
+
+ The groffer versions 1.* have two kinds of program, a shell
+ version and a Perl version.
+
+ The shell version is kept from the old shell only versions of
+ groffer 0.*. Most of the former files in the main groffer
+ directory are now moved to the subdirectoy shell/.
+
+ The Perl version of groffer is a complete rewrite; most of its
+ files are found in the subdirectory perl/.
+
+ The Makefile.sub decides whether the shell or Perl version of
+ groffer is installed. This is done by the program perl_test.pl.
+
+ In the following, all files in the groffer directory tree are
+ mentioned.
+
+ * ChangeLog: This file. It contains information for `groffer'
+ versions >= 1.0.0 with shell and Perl kinds. For older `groffer'
+ versions, see `shell/ChangeLog.0' which contains information for the
+ shell only versions of groffer 0.*.
+
+ * Makefile.sub: The old `Makefile.sub' was extended to support the
+ shell and the Perl version of `groffer' at the same time. If the
+ test of `perl_test.pl' succeeds the `groffer' Perl version will be
+ installed, otherwise the shell version is used.
+
+ * perl_test.pl: This is used by `Makefile.sub' and installed with
+ the Perl version of `groffer'. It is a test of the installed perl
+ version. The installed Perl version should be greater or equal
+ than the version that is required by this file.
+
+ * version.sh: This is the old file kept from the shell version of
+ `groffer'. It stores the `groffer' version, the date of the last
+ update, and the `groff' version. It is used and installed for the
+ shell and Perl version of `groffer'.
+
+ * README: This is the old `README' file extended by information on
+ the shell and Perl kinds of `groffer'.
+
+ * perl/: Subdirectory for the Perl version of `groffer'.
+
+ * perl/groffer.pl: This is the `groffer' script of the Perl
+ version, a Perl source file that handles the complete groffer
+ functionality.
+
+ * perl/man.pl: This is the collection of functions that are
+ related to man pages, `apropos', and `whatis'. It is loaded by
+ `perl/groffer.pl'.
+
+ * perl/func.pl: This is the collection of miscellaneous functions.
+ It is loaded by `perl/groffer.pl'.
+
+ * perl/split_env.sh: A shell script that is used by
+ `perl/groffer.pl' to split a large shell environment variable to a
+ Perl array.
+
+ * perl/groffer.man: This is the man page of the Perl version of
+ `groffer'. It is derived from `groffer.man' of the shell version.
+ It will only be installed when the `Makefile.sub' chooses to
+ install the Perl version of 'groffer' instead of the shell
+ version.
+
+ * perl/README_PERL: This file contains information of the Perl
+ compatibility and details that are special to the Perl version.
+
+ * shell/: Subdirectory for the shell version of `groffer'.
+
+ * shell/ChangeLog.0: The former `ChangeLog' file of the groffer
+ versions 0.* was moved to this file. It contains information of
+ the shell only version of groffer 0.*.
+
+ * shell/groffer.sh: This is the old `groffer.sh' file of the shell
+ version.
+
+ * shell/groffer2.sh: This is the old `groffer2.sh' file of the
+ shell version.
+
+ * shell/groffer.man: This is the old man page groffer.man of the
+ shell version. The shell version keeps its own man page. It will
+ only be installed when the `Makefile.sub' chooses to install the
+ shell version instead of the Perl version.
+
+ * shell/README_SH: This is the old `README_SH' file of the shell
+ version containing information of the shell compatibility.
+
+ The former part of the ChangeLog file is in `shell/ChangeLog.0'.
+
+2006-10-01 Bernd Warken <groff-bernd.warken-72@web.de>
+________________________________________________________________
+License
+
+Copyright (C) 2006-2009, 2011
+ Free Software Foundation, Inc.
+Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+Copying and distribution of this file, with or without
+modification, are permitted provided the copyright notice and this
+notice are preserved.
+
+This file is part of `groffer', which is part of the `groff'
+project.
+
+####### Emacs settings
+
+Local Variables:
+mode: change-log
+End:
diff --git a/contrib/groffer/Makefile.sub b/contrib/groffer/Makefile.sub
new file mode 100644
index 00000000..f0282dda
--- /dev/null
+++ b/contrib/groffer/Makefile.sub
@@ -0,0 +1,149 @@
+# Makefile.sub for `groffer' (integration into the `groff' source tree)
+
+# File position: <groff-source>/contrib/groffer/Makefile.sub
+
+# Copyright (C) 2001, 2002, 2005, 2006, 2009, 2011
+# Free Software Foundation, Inc.
+# Written by Werner Lemberg <wl@gnu.org> and
+# Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 17 Oct 2011
+
+# This file is part of `groffer' which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+########################################################################
+
+ROFF2MODES=dvi html pdf ps text x
+ROFF2PROGS=`echo $(ROFF2MODES) | sed 's/[a-z][a-z]*/roff2&/g'`
+ROFF2MAN=`echo $(ROFF2MODES) | sed 's/[a-z][a-z]*/roff2&.man/g'`
+ROFF2MANN=`echo $(ROFF2MODES) | sed 's/[a-z][a-z]*/roff2&.n/g'`
+
+MAN1=groffer.n \
+ roff2dvi.n \
+ roff2html.n \
+ roff2pdf.n \
+ roff2ps.n \
+ roff2text.n \
+ roff2x.n
+
+MOSTLYCLEANADD=groffer HAVE_PERL HAVE_SHELL groffer.man \
+ $(MAN1) $(ROFF2MAN) $(ROFF2PROGS)
+
+# not all make programs have $(RM) predefined.
+RM=rm -f
+
+all: groffer
+
+GROFFER_PERL=$(srcdir)/perl/func.pl \
+ $(srcdir)/perl/man.pl \
+ $(srcdir)/perl/perl_test.pl \
+ $(srcdir)/perl/split_env.sh
+GROFFER_SHELL=$(srcdir)/shell/groffer2.sh
+GROFFER_REST=$(srcdir)/roff2.man \
+ $(srcdir)/version.sh \
+ $(srcdir)/perl/groffer.man \
+ $(srcdir)/perl/groffer.pl \
+ $(srcdir)/perl/roff2.pl \
+ $(srcdir)/shell/roff2.sh \
+ $(srcdir)/shell/groffer.man \
+ $(srcdir)/shell/groffer.sh
+
+GROFFER_PERL_=`echo $(GROFFER_PERL) | sed 's|$(srcdir)/perl/||g'`
+GROFFER_SHELL_=`echo $(GROFFER_SHELL) | sed 's|$(srcdir)/shell||g'`
+
+# TODO: Add perl check to configure script.
+groffer: $(GROFFER_PERL) $(GROFFER_SHELL) \
+ $(GROFFER_REST) $(SH_DEPS_SED_SCRIPT)
+ if perl $(srcdir)/perl/perl_test.pl 2>&1 >/dev/null; then \
+ : >HAVE_PERL; \
+ echo "Using perl version of groffer."; \
+ sed -f "$(SH_DEPS_SED_SCRIPT)" \
+ -e "s|@g@|$(g)|g" \
+ -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \
+ -e "s|@libdir@|$(DESTDIR)$(libdir)|g" \
+ -e "s|@groffer_dir@|$(DESTDIR)$(groffer_dir)|g" \
+ -e "s|@VERSION@|$(version)$(revision)|g" \
+ -e "$(SH_SCRIPT_SED_CMD)" \
+ $(srcdir)/perl/groffer.pl >$@; \
+ cp $(srcdir)/perl/groffer.man groffer.man; \
+ for f in $(ROFF2PROGS); do \
+ cp $(srcdir)/perl/roff2.pl $$f; \
+ done; \
+ else \
+ : >HAVE_SHELL; \
+ echo "Using shell version of groffer."; \
+ sed -f "$(SH_DEPS_SED_SCRIPT)" \
+ -e "s|@g@|$(g)|g" \
+ -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \
+ -e "s|@libdir@|$(DESTDIR)$(libdir)|g" \
+ -e "s|@groffer_dir@|$(DESTDIR)$(groffer_dir)|g" \
+ -e "s|@VERSION@|$(version)$(revision)|g" \
+ -e "$(SH_SCRIPT_SED_CMD)" \
+ $(srcdir)/shell/groffer.sh >$@; \
+ cp $(srcdir)/shell/groffer.man groffer.man; \
+ for f in $(ROFF2PROGS); do \
+ cp $(srcdir)/shell/roff2.sh $$f; \
+ done; \
+ fi
+ chmod +x $@
+ for m in $(ROFF2MODES); do \
+ cat $(srcdir)/roff2.man \
+ | sed 's/@ROFF2MODE@/'"$$m"'/g' > roff2$${m}.man; \
+ done
+
+install_data: groffer
+ -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir)
+ $(RM) $(DESTDIR)$(bindir)/groffer
+ $(INSTALL_SCRIPT) groffer $(DESTDIR)$(bindir)/groffer
+ for f in $(ROFF2PROGS); do \
+ $(RM) $(DESTDIR)$(bindir)/$$f; \
+ $(INSTALL_SCRIPT) $$f $(DESTDIR)$(bindir)/$$f; \
+ done
+ -test -d $(DESTDIR)$(groffer_dir) \
+ || $(mkinstalldirs) $(DESTDIR)$(groffer_dir)
+ $(RM) $(DESTDIR)$(groffer_dir)/version.sh
+ $(INSTALL_DATA) $(srcdir)/version.sh \
+ $(DESTDIR)$(groffer_dir)/version.sh
+ for f in $(GROFFER_PERL_) $(GROFFER_SHELL_); do \
+ $(RM) $(DESTDIR)$(groffer_dir)/$$f; \
+ done
+ if test -f HAVE_PERL; then \
+ for f in $(GROFFER_PERL_); do \
+ $(INSTALL_SCRIPT) $(srcdir)/perl/$$f \
+ $(DESTDIR)$(groffer_dir)/$$f; \
+ done; \
+ elif test -f HAVE_SHELL; then \
+ for f in $(GROFFER_SHELL_); do \
+ $(INSTALL_SCRIPT) $(srcdir)/shell/$$f \
+ $(DESTDIR)$(groffer_dir)/$$f; \
+ done; \
+ fi;
+
+uninstall_sub:
+ $(RM) $(DESTDIR)$(bindir)/groffer
+ for f in $(ROFF2PROGS); do $(RM) $(DESTDIR)$(bindir)/$$f; done
+ for f in $(GROFFER_PERL_) $(GROFFER_SHELL_) version.sh; do \
+ $(RM) $(DESTDIR)$(groffer_dir)/$$f; \
+ done
+ -rmdir $(DESTDIR)$(libdir)/groff/groffer
+
+########################################################################
+# Emacs settings
+########################################################################
+#
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/contrib/groffer/README b/contrib/groffer/README
new file mode 100644
index 00000000..a44d2bc2
--- /dev/null
+++ b/contrib/groffer/README
@@ -0,0 +1,123 @@
+README
+
+The `groffer' program is the easiest way to read documents written in
+some `roff' language, such as the `man pages', the manual pages in
+many operating systems. All `roff' preprocessors, such as `chem', are
+detected and executed automatically.
+
+
+Source files in this directory
+
+ChangeLog information on all changements for groffer versions 1.*
+Makefile.sub make file used by groff
+README this file, general description of the program
+version.sh information on version number and last update
+perl_test.pl test whether perl has a suitable version
+perl/ subdirectory for the Perl version, see perl/README_PERL
+shell/ subdirectory for the shell version, see shell/README_SH
+
+
+Input
+
+Input comes from either standard input or command line parameters that
+represent names of exisiting roff files or standardized specifications
+for searching man pages. All of these can be compressed in a format
+that is decompressible by `gzip' or `bzip2', including `.gz', `bz2',
+and `.Z'.
+
+`groffer' has many built-in `man' functionalities to find and read the
+manual pages on UNIX and similar operating systems. It accepts the
+information from an installed `man' program, but tries to find a man
+path by itself.
+
+`groffer' bundles all filespec parameters into a single output file in
+the same way as `groff'. The disadvantage of this is that all file
+name arguments must use the same groff language. To change this, the
+option parsing must be revised for large parts. It seems that this
+would create incompatibilities, so the actual option strategy is kept.
+
+
+Output
+
+All input is first sent to `grog' to determine the necessary `groff'
+command and then to `groff' together with all necessary preprocessors.
+So no special `groff' arguments must be given. But all `groff'
+options can be specified when this seems to be appropriate.
+
+The following displaying modes for the output are available:
+- Display formatted input with
+-- a PDF viewer,
+-- a Postcript viewer,
+-- a web browser,
+-- the X `roff' viewer `gxditview',
+-- a DVI viewer,
+-- a pager in a text terminal (tty).
+- Generate `groff' output on stdout without a viewer.
+- Generate the `groff intermediate output' on standard output without
+ postprocessing.
+- Output the source code without any `groff' processing.
+- There are some information outputs without `groff' processing, such
+ as by option `-V' and the `man' like `whatis' and `apropos'
+ outputs.
+
+By default, the program tries to display a graphical device in X; on
+non-X text terminals, the `tty' text mode with a pager is tried by
+default.
+
+
+File access
+
+The shell and the Perl version of groffer now use umask of 077. This
+is a very strict security issue. It allows only access of the
+temporary files by the file owner.
+
+
+Compatibility
+
+`groffer' is compatible with the `man' program. It supports .so
+requests based on the man path and compressed files. That's more than
+`groff' does.
+
+
+Mailing lists
+
+For reporting bugs of `groffer', groff's free mailing list
+<bug-groff@gnu.org> can be used.
+
+For a general discussion, the mailing list <groff@gnu.org> is more
+useful, but one has to subscribe to this list at
+http://lists.gnu.org/mailman/listinfo/groff.
+
+See the `README' file in the top directory of the `groff' source
+package for more details on these mailing lists.
+
+
+####### License
+
+Last update: 5 Jan 2009
+
+Copyright (C) 2003, 2004, 2005, 2006, 2009
+ Free Software Foundation, Inc.
+Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+This file is part of `groffer', which is part of `groff'.
+
+`groff' 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.
+
+`groff' 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/>.
+
+
+####### Emacs settings
+
+Local Variables:
+mode: text
+End:
diff --git a/contrib/groffer/roff2.man b/contrib/groffer/roff2.man
new file mode 100644
index 00000000..68af4291
--- /dev/null
+++ b/contrib/groffer/roff2.man
@@ -0,0 +1,249 @@
+.ig
+roff2@ROFF2MODE@.1 - man page for roff2@ROFF2MODE@ (section 1).
+
+Source file position: <groff_source_top>/contrib/groffer/roff2.man
+Installed position: $prefix/share/man/man1/roff2@ROFF2MODE@.1
+
+Last update: 5 Jan 2009
+Simplified to use .SY/.OP/.YS
+..
+.
+.
+.de au
+This file was written by Bernd Warken <groff-bernd.warken-72@web.de>.
+..
+.
+.
+.de co
+Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
+.
+.P
+This file is part of
+.IR \%groffer ,
+which is part of
+.IR \%groff ,
+a free software project.
+.
+You can redistribute it and/or modify it under the terms of the
+.nh
+.B "GNU General Public License"
+.hy
+as published by the
+.nh
+.BR "Free Software Foundation" ,
+.hy
+either version\~2, or (at your option) any later version.
+.
+.P
+You should have received a copy of the \f[CR]GNU General Public
+License\f[] along with
+.IR groff ,
+see the files \%\f[CB]COPYING\f[] and \%\f[CB]LICENSE\f[] in the top
+directory of the
+.I groff
+source package.
+.
+Or read the
+.I man\~page
+.BR gpl (1).
+You can also write to the
+.nh
+.B "Free Software Foundation, 51 Franklin St - Fifth Floor, Boston,"
+.BR "MA 02110-1301, USA" .
+.hy
+..
+.
+.
+.TH roff2@ROFF2MODE@ @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@"
+.SH NAME
+roff2@ROFF2MODE@ \- transform roff code into @ROFF2MODE@ mode
+.
+.
+.\" --------------------------------------------------------------------
+.SH "SYNOPSIS"
+.
+.SY roff2@ROFF2MODE@
+.RI [ \%groffer_option .\|.\|.\&]
+.OP \-\-
+.RI [ \%filespec .\|.\|.\&]
+.
+.SY roff2@ROFF2MODE@
+.B \-h
+|
+.B \-\-help
+.
+.SY roff2@ROFF2MODE@
+.B \-v
+|
+.B \-\-version
+.YS
+.
+.P
+The options
+.B \-v
+and
+.B \%\-\-version
+print the version information of the program to standard output and exit.
+.
+The options
+.B \-h
+and
+.B \-\-help
+print a usage information of the program to standard output and stop
+the program instantly.
+.
+.
+.P
+All other options are assumed to be
+.B \%groffer
+options.
+.
+They are internally passed to
+.BR \%groffer .
+They override the behavior of the program.
+.
+The options are optional, they can be omitted.
+.
+.
+.P
+The
+.I \%filespec
+arguments correspond to the
+.I \%filespec
+arguments of
+.BR \%groffer .
+So they are either the names of existing, readable files or
+.B \-
+for standard input, or the name of a man page or a
+.BR \%groffer (@MAN1EXT@)
+man page search pattern.
+.
+If no
+.I \%filespec
+is specified standard input is assumed automatically.
+.
+.
+.\" --------------------------------------------------------------------
+.SH DESCRIPTION
+.
+.B \%roff2@ROFF2MODE@
+transforms
+.I roff
+code into
+.ie '@ROFF2MODE@'x' \{\
+. I X
+mode corresponding to the
+. I groff
+devices
+. BR X *;
+this mode is suitable for
+. BR \%gxditview (@MAN1EXT@).
+.\}
+.el \{\
+. I \%@ROFF2MODE@
+mode.
+.\}
+.
+Print the result to standard output.
+.
+.
+.P
+There are more of these programs for generating other formats of
+.I \%roff
+input.
+.
+.if !'@ROFF2MODE@'dvi' \{\
+. TP
+. BR \%roff2dvi (@MAN1EXT@)
+is for
+. I dvi
+mode.
+.\}
+.
+.if !'@ROFF2MODE@'html' \{\
+. TP
+. BR \%roff2html (@MAN1EXT@)
+generates
+. I html
+output.
+.\}
+.
+.if !'@ROFF2MODE@'pdf' \{\
+. TP
+. BR \%roff2pdf (@MAN1EXT@)
+outputs
+. I pdf
+mode.
+.\}
+.
+.if !'@ROFF2MODE@'ps' \{\
+. TP
+. BR \%roff2ps (@MAN1EXT@)
+prints
+. I \%PostScript
+format to standard output.
+.\}
+.
+.if !'@ROFF2MODE@'text' \{\
+. TP
+. BR \%roff2text (@MAN1EXT@)
+generates text output in the
+. B groff
+device
+. IR latin1 .
+.\}
+.
+.if !'@ROFF2MODE@'x' \{\
+. TP
+. BR \%roff2x (@MAN1EXT@)
+prints the output in the
+. B groff
+device
+. B X
+that is suitable for programs like
+. BR \%gxditview (@MAN1EXT@)
+or
+. BR \%xditview (1).
+.\}
+.
+.
+.\" --------------------------------------------------------------------
+.SH "SEE ALSO"
+.\" --------------------------------------------------------------------
+.
+.BR \%groff (@MAN1EXT@),
+.BR \%groffer (@MAN1EXT@),
+.if !'@ROFF2MODE@'dvi' \
+. BR \%roff2dvi (@MAN1EXT@),
+.if !'@ROFF2MODE@'html' \
+. BR \%roff2html (@MAN1EXT@),
+.if !'@ROFF2MODE@'pdf' \
+. BR \%roff2pdf (@MAN1EXT@),
+.if !'@ROFF2MODE@'ps' \
+. BR \%roff2ps (@MAN1EXT@),
+.if !'@ROFF2MODE@'text' \
+. BR \%roff2text (@MAN1EXT@),
+.if !'@ROFF2MODE@'x' \
+. BR \%roff2x (@MAN1EXT@),
+.BR \%gxditview (@MAN1EXT@).
+.
+.
+.\" --------------------------------------------------------------------
+.SH "AUTHOR"
+.\" --------------------------------------------------------------------
+.au
+.
+.
+.\" --------------------------------------------------------------------
+.SH "COPYING"
+.\" --------------------------------------------------------------------
+.co
+.
+.
+.\" --------------------------------------------------------------------
+.\" Emacs settings
+.\" --------------------------------------------------------------------
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/contrib/groffer/version.sh b/contrib/groffer/version.sh
new file mode 100644
index 00000000..447b24f3
--- /dev/null
+++ b/contrib/groffer/version.sh
@@ -0,0 +1,38 @@
+#! /bin/sh
+
+# groffer - display groff files
+
+# Source file position: <groff-source>/contrib/groffer/version.sh
+# Installed position: <prefix>/lib/groff/groffer/version.sh
+
+# Copyright (C) 2001-2006, 2009, 2011, 2013
+# Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# This file is part of `groffer', which is part of `groff'.
+
+# `groff' 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.
+
+# `groff' 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/>.
+
+########################################################################
+
+export _PROGRAM_VERSION;
+export _LAST_UPDATE;
+
+_PROGRAM_VERSION='1.1.3';
+_LAST_UPDATE='29 Mar 2013';
+
+# this setting of the groff version is only used before make is run,
+# otherwise @VERSION@ will set it, see groffer.sh.
+export _GROFF_VERSION_PRESET;
+_GROFF_VERSION_PRESET='1.22.2';