summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwl <wl>2013-08-11 08:28:51 +0000
committerwl <wl>2013-08-11 08:28:51 +0000
commitdd226e578e7a8a0a13826c0039318e6ce7869141 (patch)
treeacadf1aff352fc7bbbe4b41c39c391442ec4780b
parent2e4ed555a4ce1fcb09d45c9b829de0480390fe67 (diff)
downloadgroff-dd226e578e7a8a0a13826c0039318e6ce7869141.tar.gz
Revert accidental removal of previous commit.
-rw-r--r--contrib/chem/examples/122/README.txt74
-rw-r--r--contrib/chem/examples/122/ch2a_ethyl.chem43
-rw-r--r--contrib/chem/examples/122/ch2b_benzene.chem40
-rw-r--r--contrib/chem/examples/122/ch2c_benzene_right.chem40
-rw-r--r--contrib/chem/examples/122/ch4a_stick.chem45
-rw-r--r--contrib/chem/examples/122/ch4b_methyl_acetate.chem49
-rw-r--r--contrib/chem/examples/122/ch4c_colon.chem44
-rw-r--r--contrib/chem/examples/122/ch4d_HCl.H2O.chem40
-rw-r--r--contrib/chem/examples/122/ch4e_CaSO4.2H2O.chem40
-rw-r--r--contrib/chem/examples/122/ch4f_C.chem50
-rw-r--r--contrib/chem/examples/122/ch4g_BP.chem50
-rw-r--r--contrib/chem/examples/122/ch4h_methacrylate.chem67
-rw-r--r--contrib/chem/examples/122/ch4i_cyclo.chem47
-rw-r--r--contrib/chem/examples/122/ch4j_ring4.chem40
-rw-r--r--contrib/chem/examples/122/ch4k_ring3.chem42
-rw-r--r--contrib/chem/examples/122/ch4l_vertex.chem47
-rw-r--r--contrib/chem/examples/122/ch4m_double.chem40
-rw-r--r--contrib/chem/examples/122/ch4n_triple.chem40
-rw-r--r--contrib/chem/examples/122/ch4o_aromatic.chem41
-rw-r--r--contrib/chem/examples/122/ch4p_cholestanol.chem62
-rw-r--r--contrib/chem/examples/122/ch4q_rings.chem48
-rw-r--r--contrib/chem/examples/122/ch4r_spiro.chem44
-rw-r--r--contrib/chem/examples/122/ch4s_heteroatoms.chem40
-rw-r--r--contrib/chem/examples/122/ch4t_polycyclic.chem51
-rw-r--r--contrib/chem/examples/122/ch4u_nicotine.chem44
-rw-r--r--contrib/chem/examples/122/ch4v_histidine.chem46
-rw-r--r--contrib/chem/examples/122/ch4w_lsd.chem52
-rw-r--r--contrib/chem/examples/122/ch4x_anisole.chem44
-rw-r--r--contrib/chem/examples/122/ch4y_reserpine.chem64
-rw-r--r--contrib/chem/examples/122/ch4z1_eqn_glutamic.chem80
-rw-r--r--contrib/chem/examples/122/ch4z2_text.chem55
-rw-r--r--contrib/chem/examples/122/ch5a_size.chem47
-rw-r--r--contrib/chem/examples/122/ch6a_pic.chem45
-rw-r--r--contrib/chem/examples/122/ch6b_dna.chem61
-rw-r--r--contrib/chem/examples/122/chAa_polymer.chem74
-rw-r--r--contrib/chem/examples/122/chAb_vinyl_chloro.chem64
-rw-r--r--contrib/chem/examples/122/chAc_morphine.chem54
-rw-r--r--contrib/chem/examples/122/chAd_chlorophyll.chem71
-rw-r--r--contrib/chem/examples/122/chAe_chair.chem51
-rw-r--r--contrib/chem/examples/122/chAf_arrow.chem70
-rw-r--r--contrib/chem/examples/122/chAg_circle.chem56
-rw-r--r--contrib/chem/examples/122/chAh_brackets.chem62
-rw-r--r--contrib/chem/examples/122/chAi_poly_vinyl_chloride.chem143
-rw-r--r--contrib/chem/examples/122/chBa_jump.chem43
-rw-r--r--contrib/chem/examples/122/chBb_bonds.chem44
-rw-r--r--contrib/chem/examples/122/chBc_rings.chem45
-rw-r--r--contrib/groffer/perl/README_PERL263
-rw-r--r--contrib/groffer/perl/func.pl789
-rw-r--r--contrib/groffer/perl/groffer.man3920
-rwxr-xr-xcontrib/groffer/perl/groffer.pl2209
-rw-r--r--contrib/groffer/perl/man.pl731
-rw-r--r--contrib/groffer/perl/perl_test.pl34
-rwxr-xr-xcontrib/groffer/perl/roff2.pl223
-rw-r--r--contrib/groffer/perl/split_env.sh48
54 files changed, 10656 insertions, 0 deletions
diff --git a/contrib/chem/examples/122/README.txt b/contrib/chem/examples/122/README.txt
new file mode 100644
index 00000000..e6ecde80
--- /dev/null
+++ b/contrib/chem/examples/122/README.txt
@@ -0,0 +1,74 @@
+This directory contains the examples for the `chem' language written
+in the book:
+
+ Computing Science Technical Report No. 122
+ CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+ by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+
+The book is available in the internet at
+<http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+Many of the examples had to be fixed. Unfortunately, the `chem' akw
+version does not run on many of these programs. But the Perl version
+of `chem' works on all examples.
+
+Most examples do not use the modern chemical display. They have C
+atoms added, whereas the modern method omits all C atoms and their
+directly appended H atoms.
+
+The examples are named and sorted by the chapter where they are found
+in the book. For example, the file `ch4c_colon.chem' means a `chem'
+example in chapter 4; according to `c', it is the third example in
+this chapter; the name `colon' is used to describe the context of the
+example.
+
+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 ...
+
+
+####### 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/122/ch2a_ethyl.chem b/contrib/chem/examples/122/ch2a_ethyl.chem
new file mode 100644
index 00000000..0f1ca613
--- /dev/null
+++ b/contrib/chem/examples/122/ch2a_ethyl.chem
@@ -0,0 +1,43 @@
+ch2a_ethyl.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ CH3
+ bond
+ CH2
+ bond
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch2b_benzene.chem b/contrib/chem/examples/122/ch2b_benzene.chem
new file mode 100644
index 00000000..d9e492da
--- /dev/null
+++ b/contrib/chem/examples/122/ch2b_benzene.chem
@@ -0,0 +1,40 @@
+ch2b_benzene.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ benzene
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch2c_benzene_right.chem b/contrib/chem/examples/122/ch2c_benzene_right.chem
new file mode 100644
index 00000000..ab4c956d
--- /dev/null
+++ b/contrib/chem/examples/122/ch2c_benzene_right.chem
@@ -0,0 +1,40 @@
+ch2c_benzene_right.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ benzene pointing right # a rotated benzene ring
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4a_stick.chem b/contrib/chem/examples/122/ch4a_stick.chem
new file mode 100644
index 00000000..f561f2a9
--- /dev/null
+++ b/contrib/chem/examples/122/ch4a_stick.chem
@@ -0,0 +1,45 @@
+ch4a_stick.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ bond right
+ bond 60
+ bond 120
+ bond 60
+ bond 120
+ bond down
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4b_methyl_acetate.chem b/contrib/chem/examples/122/ch4b_methyl_acetate.chem
new file mode 100644
index 00000000..a519289f
--- /dev/null
+++ b/contrib/chem/examples/122/ch4b_methyl_acetate.chem
@@ -0,0 +1,49 @@
+ch4b_methyl_acetate.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+CH3 # the 3 is automatically turned into a subscript
+bond # the implicit direction is right
+ # implicit connection is to right side of CH3
+C
+double bond 30 # by default, from the substituent C
+O
+bond 120 from C # must be "from C"; otherwise would leave from O
+O
+bond right
+CH3
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4c_colon.chem b/contrib/chem/examples/122/ch4c_colon.chem
new file mode 100644
index 00000000..19d156f7
--- /dev/null
+++ b/contrib/chem/examples/122/ch4c_colon.chem
@@ -0,0 +1,44 @@
+ch4c_colon.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ CH3
+ bond ; C
+ double bond 30 ; O
+ bond 120 from C ; O
+ bond right ; CH3
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4d_HCl.H2O.chem b/contrib/chem/examples/122/ch4d_HCl.H2O.chem
new file mode 100644
index 00000000..9f57edc5
--- /dev/null
+++ b/contrib/chem/examples/122/ch4d_HCl.H2O.chem
@@ -0,0 +1,40 @@
+ch4d_HCl.H2O.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ HCl.H2O
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4e_CaSO4.2H2O.chem b/contrib/chem/examples/122/ch4e_CaSO4.2H2O.chem
new file mode 100644
index 00000000..06d308bf
--- /dev/null
+++ b/contrib/chem/examples/122/ch4e_CaSO4.2H2O.chem
@@ -0,0 +1,40 @@
+ch4e_CaSO4.2H2O.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ CaSO4.2H2O
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4f_C.chem b/contrib/chem/examples/122/ch4f_C.chem
new file mode 100644
index 00000000..496db1cc
--- /dev/null
+++ b/contrib/chem/examples/122/ch4f_C.chem
@@ -0,0 +1,50 @@
+ch4f_C.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ bond ; C # 1st definition of C
+ bond up from C
+ bond down from C
+ bond right from C ; C # 2nd definition of C
+ bond up from C
+ bond down from C
+ bond right from C ; C # 3rd definition of C
+ bond up from C
+ bond down from C
+ bond right from C
+
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4g_BP.chem b/contrib/chem/examples/122/ch4g_BP.chem
new file mode 100644
index 00000000..1f7783c1
--- /dev/null
+++ b/contrib/chem/examples/122/ch4g_BP.chem
@@ -0,0 +1,50 @@
+ch4g_BP.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+# this is the isopropyl group
+ bond 120 ; BP # BP is right end of this bond
+ bond -120 from BP
+ bond right from BP ; C
+ front bond up ; CH3
+ back bond down from C ; D
+ bond right from C ; BP
+# redefine BP to mean the center carbon of this t-butyl group
+ bond up from BP
+ bond right from BP
+ bond down from BP
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4h_methacrylate.chem b/contrib/chem/examples/122/ch4h_methacrylate.chem
new file mode 100644
index 00000000..ba8e9c1d
--- /dev/null
+++ b/contrib/chem/examples/122/ch4h_methacrylate.chem
@@ -0,0 +1,67 @@
+ch4h_methacrylate.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ bond dotted
+ bond right ; BP
+ bond up from BP ; C
+ double bond -60 from C ; O
+ bond 60 length .1 from C ; OCH3
+ bond down from BP ; CH3
+# begin second segment of polymer
+ bond right length .5 from BP ; BP
+ bond up length .1 from BP ; H
+ bond down length .1 from BP ; H
+# begin third segment of polymer
+ bond right length .5 from BP ; BP
+ bond up from BP ; C
+ double bond -60 from C ; O
+ bond 60 length .1 from C ; OCH3
+ bond down from BP ; CH3
+# begin fourth segment of polymer
+ bond right length .5 from BP ; BP
+ bond up length .1 from BP ; H
+ bond down length .1 from BP ; H
+# begin fifth segment of polymer
+ bond right length .5 from BP ; BP
+ bond up from BP ; C
+ double bond -60 from C ; O
+ bond 60 length .1 from C ; OCH3
+ bond down from BP ; CH3
+ bond right from BP
+ bond dotted
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4i_cyclo.chem b/contrib/chem/examples/122/ch4i_cyclo.chem
new file mode 100644
index 00000000..70416c2f
--- /dev/null
+++ b/contrib/chem/examples/122/ch4i_cyclo.chem
@@ -0,0 +1,47 @@
+ch4i_cyclo.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+R3: ring3
+R4: ring4 at R3 + (.75,0)
+R5: ring5 at R4 + (.75,0)
+R6: ring6 at R5 + (.75,0)
+B: benzene at R6 + (.75,0)
+R7: ring7 at B + (.75,0)
+R8: ring8 at R7 + (.75,0)
+
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4j_ring4.chem b/contrib/chem/examples/122/ch4j_ring4.chem
new file mode 100644
index 00000000..97698732
--- /dev/null
+++ b/contrib/chem/examples/122/ch4j_ring4.chem
@@ -0,0 +1,40 @@
+ch4j_ring4.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ ring4 pointing 45
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4k_ring3.chem b/contrib/chem/examples/122/ch4k_ring3.chem
new file mode 100644
index 00000000..79298440
--- /dev/null
+++ b/contrib/chem/examples/122/ch4k_ring3.chem
@@ -0,0 +1,42 @@
+ch4k_ring3.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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: ring3
+ back bond 120 from R.V2 ; C2H5
+ front bond -120 from R.V3 ; HO
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4l_vertex.chem b/contrib/chem/examples/122/ch4l_vertex.chem
new file mode 100644
index 00000000..75d2930f
--- /dev/null
+++ b/contrib/chem/examples/122/ch4l_vertex.chem
@@ -0,0 +1,47 @@
+ch4l_vertex.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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: benzene pointing right
+ bond left from R.V4 ; HO
+ bond -150 from R.V3 ; CH3O
+ bond right from R.V1 ; C
+ double bond up from C ; O
+ bond right from C ; N
+ bond 45 ; C2H5
+ bond 135 from N ; C2H5
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4m_double.chem b/contrib/chem/examples/122/ch4m_double.chem
new file mode 100644
index 00000000..0efdfc4d
--- /dev/null
+++ b/contrib/chem/examples/122/ch4m_double.chem
@@ -0,0 +1,40 @@
+ch4m_double.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ ring double 1,2 3,4 5,6
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4n_triple.chem b/contrib/chem/examples/122/ch4n_triple.chem
new file mode 100644
index 00000000..d8bdb1bd
--- /dev/null
+++ b/contrib/chem/examples/122/ch4n_triple.chem
@@ -0,0 +1,40 @@
+ch4n_triple.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ ring8 triple 3,4
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4o_aromatic.chem b/contrib/chem/examples/122/ch4o_aromatic.chem
new file mode 100644
index 00000000..797ab383
--- /dev/null
+++ b/contrib/chem/examples/122/ch4o_aromatic.chem
@@ -0,0 +1,41 @@
+ch4o_aromatic.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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: aromatic ring7
+ "+" at R
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4p_cholestanol.chem b/contrib/chem/examples/122/ch4p_cholestanol.chem
new file mode 100644
index 00000000..3e02b9e6
--- /dev/null
+++ b/contrib/chem/examples/122/ch4p_cholestanol.chem
@@ -0,0 +1,62 @@
+ch4p_cholestanol.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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
+ "R1" at R1 # this puts a label at R1
+ front bond -120 from R1.V5 ; HO
+ # the following line says "fuse the next six-
+ # membered ring with its 6th vertex joining
+ # the second vertex of R1"
+R2: ring6 with .V6 at R1.V2
+ front bond up from R2.V6 ; CH3
+ back bond down from R2.V4 ; H
+ back bond down from R2.V1 ; H
+ front bond up from R2.V2 ; H
+R3: ring6 with .V4 at R2.V2
+R4: flatring with .V5 at R3.V2
+ front bond up from R4.V5 ; CH3
+ back bond down from R4.V4 ; H # this is the alkyl chain
+ bond up from R4.V1 ; BP
+ bond -60 from BP
+ bond 60 from BP
+ bond 120
+ bond 60
+ bond 120 ; BP
+ bond down from BP
+ bond 60 from BP
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4q_rings.chem b/contrib/chem/examples/122/ch4q_rings.chem
new file mode 100644
index 00000000..21abd84f
--- /dev/null
+++ b/contrib/chem/examples/122/ch4q_rings.chem
@@ -0,0 +1,48 @@
+ch4q_rings.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+R3: ring3
+R4: ring4 pointing 45 with .V1 at R3.V2
+R5: ring5 pointing down with .V4 at R4.V2
+R6: ring6 pointing 54 with .V6 at R5.V5
+ # the following lines specify the labels inside the rings
+ "3" at R3
+ "4" at R4
+ "5" at R5
+ "6" at R6
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4r_spiro.chem b/contrib/chem/examples/122/ch4r_spiro.chem
new file mode 100644
index 00000000..3440c384
--- /dev/null
+++ b/contrib/chem/examples/122/ch4r_spiro.chem
@@ -0,0 +1,44 @@
+ch4r_spiro.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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
+R2: ring6 with .V1 at R1.V4
+R3: ring5 with .V5 at R2.V3
+ back bond 60 from R3.V2 ; OH
+ front bond 150 from R3.V3 ; OH
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4s_heteroatoms.chem b/contrib/chem/examples/122/ch4s_heteroatoms.chem
new file mode 100644
index 00000000..8d944924
--- /dev/null
+++ b/contrib/chem/examples/122/ch4s_heteroatoms.chem
@@ -0,0 +1,40 @@
+ch4s_heteroatoms.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ ring put N at 2 put S at 4 double 2,3 4,5 6,1
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4t_polycyclic.chem b/contrib/chem/examples/122/ch4t_polycyclic.chem
new file mode 100644
index 00000000..5044dc40
--- /dev/null
+++ b/contrib/chem/examples/122/ch4t_polycyclic.chem
@@ -0,0 +1,51 @@
+ch4t_polycyclic.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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 right
+ bond 30 from R1.V6 ; Br
+R2: benzene pointing right with .V5 at R1.V1
+R3: benzene pointing right with .V1 at R2.V3
+ bond 150 from R3.V2 ; CO2H
+R4: benzene pointing right with .V1 at R1.V3
+# next line names bond B1 so we can refer to its end
+B1: bond left from R4.V4
+ ring6 put N at 4 double 2,3 4,5 6,1 with .V3 at B1.end
+B2: bond right from R2.V1
+R5: benzene with .V5 at B2.end
+ ring6 put N at 4 double 1,2 3,4 with .V5 at R5.V3
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4u_nicotine.chem b/contrib/chem/examples/122/ch4u_nicotine.chem
new file mode 100644
index 00000000..5f0e0245
--- /dev/null
+++ b/contrib/chem/examples/122/ch4u_nicotine.chem
@@ -0,0 +1,44 @@
+ch4u_nicotine.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ benzene put N at 4
+ bond right
+ ring5 pointing down put N at 1
+ bond down from .N ; CH3 # or .V1
+
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4v_histidine.chem b/contrib/chem/examples/122/ch4v_histidine.chem
new file mode 100644
index 00000000..819da05c
--- /dev/null
+++ b/contrib/chem/examples/122/ch4v_histidine.chem
@@ -0,0 +1,46 @@
+ch4v_histidine.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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: flatring pointing down put N at 2 put N at 5 double 1,2 3,4
+ H right of R1.V5
+ bond right from R1.V4 ; CH2
+ bond right ; C
+ bond up from C ; H
+ bond down from C ; NH2
+ bond right from C ; CO2H
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4w_lsd.chem b/contrib/chem/examples/122/ch4w_lsd.chem
new file mode 100644
index 00000000..53256871
--- /dev/null
+++ b/contrib/chem/examples/122/ch4w_lsd.chem
@@ -0,0 +1,52 @@
+ch4w_lsd.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+B: benzene pointing right
+F: flatring pointing left put N at 5 double 3,4 with .V1 at B.V2
+ H below F.N
+R: ring pointing right with .V4 at B.V6
+ front bond right from R.V6 ; H
+W: ring pointing right with .V2 at R.V6 put N at 1 double 3,4
+ bond right from W.N ; CH3
+ back bond -60 from W.V5 ; H
+ bond up from W.V5 ; C
+ double bond up from C ; O
+ bond right from C ; N
+ bond 45 from N ; C2H5
+ bond 135 from N ; C2H5
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4x_anisole.chem b/contrib/chem/examples/122/ch4x_anisole.chem
new file mode 100644
index 00000000..48727c52
--- /dev/null
+++ b/contrib/chem/examples/122/ch4x_anisole.chem
@@ -0,0 +1,44 @@
+ch4x_anisole.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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
+ bond down from R1.V4 ; OCH3
+R2: benzene at R1 + (1.5,0)
+ bond down from R2.V4 ; O
+ CH3 right of O
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4y_reserpine.chem b/contrib/chem/examples/122/ch4y_reserpine.chem
new file mode 100644
index 00000000..e8223955
--- /dev/null
+++ b/contrib/chem/examples/122/ch4y_reserpine.chem
@@ -0,0 +1,64 @@
+ch4y_reserpine.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+# Some corrections were added.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ CH3O
+ bond 60
+R1: benzene
+R2: aromatic flatring5 pointing down put N at 1 with .V3 at R1.V2
+ 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 ; C
+ double bond down from C ; O
+ CH3O left of C
+ back bond 60 from R5.V3 ; H
+ back bond down from R5.V4 ; O
+ CH3 right of O
+ bond 120 from R5.V3 ; O
+ bond right length .1 from O ; C
+ double bond down ; O
+ bond right length .1 from C
+B: benzene pointing right
+ bond 30 from B.V6 ; OCH3
+ bond right from B.V1 ; OCH3
+ bond 150 from B.V2 ; OCH3
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch4z1_eqn_glutamic.chem b/contrib/chem/examples/122/ch4z1_eqn_glutamic.chem
new file mode 100644
index 00000000..0ad7bb1a
--- /dev/null
+++ b/contrib/chem/examples/122/ch4z1_eqn_glutamic.chem
@@ -0,0 +1,80 @@
+ch4z1_eqn_glutamic.chem:
+.br
+.EQ
+delim $$
+.EN
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+# Some corrections were added.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+# a left bracket
+ bond right length .1 ; BP
+ bond up length .3
+ bond right length .1
+ bond down length .3 from BP
+ bond right length .1
+# this is the mainchain amide structure
+ bond right length .1 from BP ; NH
+ bond right ; CH
+# label the CH with an alpha, intended for eqn.
+# this line says "put the north edge of the alpha at the
+# south edge of the CH"
+ "$alpha$" with .n at CH.s
+ bond right from CH ; C
+ double bond up from C ; O
+ bond right length .1 from C ; BP
+# a right bracket
+ bond up length .3
+ bond left length .1
+ bond right length .1 from BP
+ bond down length .3 from BP ; BP
+ bond left length .1
+# label the degree of polymerization
+ "$n$" with .w at BP.se
+# this is the sidechain
+ bond up from CH ; CH2
+ "$beta$" with .e at CH2.w
+ bond up from CH2 ; CH2
+ "$gamma$" with .e at CH2.w
+ bond up from CH2 ; C
+# this is the benzyl ester part
+ double bond -60 from C ; O
+ bond 60 from C ; O
+ bond right ; CH2C6H5
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
+.EQ
+delim off
+.EN
diff --git a/contrib/chem/examples/122/ch4z2_text.chem b/contrib/chem/examples/122/ch4z2_text.chem
new file mode 100644
index 00000000..47064ef1
--- /dev/null
+++ b/contrib/chem/examples/122/ch4z2_text.chem
@@ -0,0 +1,55 @@
+ch4z2_text.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ bond 120 dotted
+ bond 120 length .3 ; BP
+ back bond -120 length .25 from BP ; H
+ front bond 120 length .25 from BP ; CH3
+ bond 60 length .5 from BP ; BP
+ bond -60 length .25 from BP ; H
+# note the pic move command to position the text
+ move left .35 ; "(ANTI)"
+ front bond 60 length .25 from BP ; H
+# another positioning of text
+ move right .35 ; "(SYN)"
+ bond 120 length .4 from BP ; BP
+ back bond -120 length .25 from BP ; H
+ front bond 120 length .25 from BP ; CH3
+ bond 60 length .5 from BP
+ bond 60 dotted
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch5a_size.chem b/contrib/chem/examples/122/ch5a_size.chem
new file mode 100644
index 00000000..d945db31
--- /dev/null
+++ b/contrib/chem/examples/122/ch5a_size.chem
@@ -0,0 +1,47 @@
+ch5a_size.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+.ps 14
+size 16
+R: ring6 put O at 1 put C at 2 put O at 3 put C at 4 put O at 5 put C at 6
+ double bond 60 from R.V2 ; NH
+ double bond down from R.V4 ; NH
+ double bond -60 from R.V6 ; HN
+size 10 # if you are doing more than one
+.ps 10
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch6a_pic.chem b/contrib/chem/examples/122/ch6a_pic.chem
new file mode 100644
index 00000000..f444591f
--- /dev/null
+++ b/contrib/chem/examples/122/ch6a_pic.chem
@@ -0,0 +1,45 @@
+ch6a_pic.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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 double 2,3
+ line from R.V6 to R.C
+ line from R.C to R.V4
+ X1: 1/2 <R.V5,R.C>
+ X2: 1/2 <R.C,R.V2>
+ bond from X1 to X2
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/ch6b_dna.chem b/contrib/chem/examples/122/ch6b_dna.chem
new file mode 100644
index 00000000..38577db7
--- /dev/null
+++ b/contrib/chem/examples/122/ch6b_dna.chem
@@ -0,0 +1,61 @@
+ch6b_dna.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+P: [
+R1: flatring pointing up put N at 1 put N at 4 double 5,1
+ bond -135 from R1.V4 ; BP
+ "deoxyribose" rjust with .e at BP.w
+R2: ring6 put N at 2 put N at 4 double 1,2 3,4 5,6 with .V6 at R1.V2
+ pic Conn: R2.V2.ne #because naming is too restricted in pic
+ bond up from R2.V1 ; N
+ bond -60 from N ; H
+ bond 60 from N ; H
+]
+ # thymine
+Q: [
+R3: ring6 put N at 3 put N at 5 double 1,2
+ bond up from R3.V1 ; CH3
+ bond 120 from R3.V3 ; BP
+ "deoxyribose" ljust with .w at BP.e
+ double bond down from R3.V4 ; O
+ double bond -60 from R3.V6 ; O
+ bond -120 from R3.V5 ; H
+] with .O at P.H + (.3,.3)
+ bond from Q.O.sw to P.H.ne dotted
+ bond from Q.H.sw to P.Conn dotted
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chAa_polymer.chem b/contrib/chem/examples/122/chAa_polymer.chem
new file mode 100644
index 00000000..5dc8838b
--- /dev/null
+++ b/contrib/chem/examples/122/chAa_polymer.chem
@@ -0,0 +1,74 @@
+chAa_polymer.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+# epoxy based on the m-phenyldiamine cured bisphenol-A
+ size 8
+ bond dotted
+ bond ; N
+ bond ; CH2
+ bond down from N
+R1: benzene
+ bond 120 length .1 from R1.V3 ; N
+ bond right length .1 from N
+ bond down length .1 from N
+# back to the CH2
+ bond right from CH2 ; CH
+ bond down from CH ; OH
+ bond right from CH ; CH2
+ bond right ; O
+ bond right
+ benzene pointing right
+ bond right ; C
+ bond up from C ; CH3
+ bond down from C ; CH3
+ bond right from C
+ benzene pointing right
+ bond right ; O
+ bond right from O ; CH2
+ bond right ; CH
+ bond down from CH ; OH
+ bond right from CH ; CH2
+ bond right ; N
+ bond right from N
+ bond dotted
+ bond down from N
+R2: benzene
+ bond 120 length .1 from R2.V3 ; N
+ bond right length .1 from N
+ bond down length .1 from N
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chAb_vinyl_chloro.chem b/contrib/chem/examples/122/chAb_vinyl_chloro.chem
new file mode 100644
index 00000000..5f9d197c
--- /dev/null
+++ b/contrib/chem/examples/122/chAb_vinyl_chloro.chem
@@ -0,0 +1,64 @@
+chAb_vinyl_chloro.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ Cl
+ bond 120 length .25 ; BP
+ bond 60 length .25 from BP ; Cl
+B1: double bond down length .3 from BP
+ bond 120 length .35 ; BP
+# now comes the ring
+R1: ring6 double 1,2 3,4 5,6 with .V6 at BP
+ bond up length .1 from R1.V1 ; H
+ bond 60 length .1 from R1.V2 ; H
+ bond 120 from R1.V3 ; O
+ bond 60 from O ; C
+ double bond up from C ; O
+ bond 120 from C
+# continue decorating the ring
+ bond down length .1 from R1.V4 ; H
+ bond -120 length .1 from R1.V5 ; H
+# now go back and do the left hand ring
+ bond -120 length .35 from B1.end ; BP
+R2: ring6 double 1,2 3,4 5,6 with .V2 at BP
+ bond up length .1 from R2.V1 ; H
+ bond -60 length .1 from R2.V6 ; H
+ bond -120 from R2.V5 ; O
+ bond -60 from O
+ bond down length .1 from R2.V4 ; H
+ bond 120 length .1 from R2.V3 ; H
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chAc_morphine.chem b/contrib/chem/examples/122/chAc_morphine.chem
new file mode 100644
index 00000000..bd37cde9
--- /dev/null
+++ b/contrib/chem/examples/122/chAc_morphine.chem
@@ -0,0 +1,54 @@
+chAc_morphine.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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 double 1,2
+ bond -60 from R1.V6 ; HO
+R2: ring6 with .V1 at R1.V3
+ bond 60 from R2.V2 ; N
+ bond right from N ; CH3
+R3: benzene with .V1 at R2.V5
+ bond -120 from R3.V5 ; HO
+# this is the furan ring
+ bond -135 length .33 from R1.V5 ; O
+ bond -45 length .33 from R3.V6
+# this is the odd ring
+ bond up length .1 from N ; BP
+B1: bond up length .33 from R1.V4
+ bond to BP
+
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chAd_chlorophyll.chem b/contrib/chem/examples/122/chAd_chlorophyll.chem
new file mode 100644
index 00000000..99495e38
--- /dev/null
+++ b/contrib/chem/examples/122/chAd_chlorophyll.chem
@@ -0,0 +1,71 @@
+chAd_chlorophyll.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ Mg
+ bond 45 ; N
+R1: ring5 pointing up put N at 4 double 1,2 4,5 with .V4 at N
+ bond up from R1.V1 ; CH3
+ bond right from R1.V2 ; CH2CH3
+ bond 135 from Mg ; N
+R2: ring5 pointing down put N at 3 double 1,2 4,5 with .V3 at N
+ bond right from R2.V5 ; CH3
+ bond 225 from Mg ; N
+R3: ring5 pointing down put N at 4 double 3,4 with .V4 at N
+ bond -45 from Mg ; N
+R4: ring5 pointing up put N at 3 double 1,5 with .V3 at N
+ bond left from R4.V5 ; H3C
+ bond up from R4.V1 ; CH
+ double bond right length .1 from CH ; CH2
+ double bond 150 length .3 from R1.V3
+ bond to R2.V4
+R5: ring5 pointing 72 with .V5 at R2.V2
+ double bond 135 from R5.V2 ; O
+ bond down from R5.V3 ; C
+ double bond left length .1 from C ; O
+ bond down from C ; O
+ CH3 left of O
+ double bond -25 from R5.V4
+ bond down from R3.V1 ; CH2
+ CH2 left of CH2
+ bond left ; C
+ double bond -45 ; O
+ bond -135 from C ; C20H39O
+ bond left from R3.V2 ; H3C
+ double bond -150 length .3 from R4.V4
+ bond to R3.V3
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chAe_chair.chem b/contrib/chem/examples/122/chAe_chair.chem
new file mode 100644
index 00000000..23de7729
--- /dev/null
+++ b/contrib/chem/examples/122/chAe_chair.chem
@@ -0,0 +1,51 @@
+chAe_chair.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+pic define chair { [
+ V1: bond 120 length .25
+ V2: bond right length .35
+ V3: bond 150 length .35
+ V4: bond -60 length .25
+ V5: bond left length .35
+ V6: bond to V1.start
+pic ] }
+R1: chair
+R2: chair with .V1 at R1.V4.start
+bond 60 from R2.V4.start ; CH3
+bond down from R2.V4.start ; OH
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chAf_arrow.chem b/contrib/chem/examples/122/chAf_arrow.chem
new file mode 100644
index 00000000..e7566b50
--- /dev/null
+++ b/contrib/chem/examples/122/chAf_arrow.chem
@@ -0,0 +1,70 @@
+chAf_arrow.chem:
+.br
+.EQ
+delim $$
+.EN
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+ bond length .1 ; BP
+ bond up length .5
+ bond right
+ bond down length .5 from BP
+ bond right
+ bond right from BP ; C
+ double bond up ; O
+ bond right from C
+ benzene pointing right
+ bond right ; C
+ double bond up from C ; O
+ bond right from C ; O
+ bond right ; CH2
+# this is the statement to make the arrow
+ line <- from CH2.s down
+ move down .1 ; "0.085"
+ CH2CH2CH2 right of CH2
+ bond right ; O
+ bond right length .1 ; BP
+ bond up length .5 from BP
+ bond left
+ bond right length .1 from BP
+ bond down length .5 from BP ; BP
+ bond left
+ "$n$" with .w at BP.se
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
+.EQ
+delim off
+.EN
diff --git a/contrib/chem/examples/122/chAg_circle.chem b/contrib/chem/examples/122/chAg_circle.chem
new file mode 100644
index 00000000..b51c9d98
--- /dev/null
+++ b/contrib/chem/examples/122/chAg_circle.chem
@@ -0,0 +1,56 @@
+chAg_circle.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+bond 120 ; C
+bond 60 ; C
+bond up ; Cl
+double bond 120 from C ; C
+bond 60 ; C
+bond 120 ; C
+bond 60 ; C
+bond up ; Cl
+double bond 120 from C ; C
+circle at C rad .08
+bond 60 from C ; C
+bond 120 ; C
+bond 60 ; C
+double bond 120 ; C
+bond down ; Cl
+bond 60 from C ; C
+bond 120
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chAh_brackets.chem b/contrib/chem/examples/122/chAh_brackets.chem
new file mode 100644
index 00000000..c45df5d6
--- /dev/null
+++ b/contrib/chem/examples/122/chAh_brackets.chem
@@ -0,0 +1,62 @@
+chAh_brackets.chem:
+.br
+.EQ
+delim $$
+.EN
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+[
+ bond right ; CH2
+ bond 120 ; (CH2)
+ "$nothing sub n$"
+ bond 60 ; .CH2
+]
+# now put the arrow in
+ move right .3
+ arrow .5
+ move right .3
+# begin second structure
+[
+ bond right ; CH.
+ bond 120 ; (CH2)
+ "$nothing sub n$"
+ bond 60 ; CH3
+]
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
+.EQ
+delim $$
+.EN
diff --git a/contrib/chem/examples/122/chAi_poly_vinyl_chloride.chem b/contrib/chem/examples/122/chAi_poly_vinyl_chloride.chem
new file mode 100644
index 00000000..ea0be896
--- /dev/null
+++ b/contrib/chem/examples/122/chAi_poly_vinyl_chloride.chem
@@ -0,0 +1,143 @@
+chAi_poly_vinyl_chloride.chem:
+.br
+.ps -2
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+db = .12
+cwid = .095
+A: [
+ bond dotted
+ bond right ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; C.
+ bond down ; Cl
+ bond right from C ; CH2
+ bond ; CH2
+ bond down ; Cl
+]
+" (6.13a)" ljust at A.e
+arrow down .5 from A.s
+[
+ CH2
+ double bond right ; CHCl
+] with .w at last arrow.c
+B: [
+ bond dotted
+ bond right ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; C
+ bond up ; Cl
+ bond down from C ; CH2
+ bond ; CH2Cl
+ bond right from C ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH
+ bond dotted
+] with .n at end of last arrow
+" (6.13b)" ljust at B.e
+C: [
+ bond dotted
+ bond right ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; C.
+ bond down ; Cl
+ bond right from C ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; CH2
+ bond down ; Cl
+] with .n at B.s - (0,.5)
+" (6.14a)" ljust at C.e
+arrow down .3 from C.s
+[
+ CH2
+ double bond right
+ CHCl
+] with .w at last arrow.s
+arrow down .3 from last arrow.s
+
+D: [
+ bond dotted
+ bond right ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; C
+ bond up ; Cl
+ bond down from C ; CH2
+ bond ; CHCl
+ bond ; CH2
+ bond ; CH2Cl
+ bond right from C ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH
+ bond dotted
+] with .n at last arrow.s
+" (6.14b)" ljust at D.e
+E: [
+ bond dotted
+ bond ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; CH
+ bond down ; Cl
+ bond right from CH ; CH2
+ bond ; CH
+ bond down ; Cl
+] with .e at B.w - (.5,0)
+
+arrow from E.ne to A.sw
+arrow from E.se to C.nw
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
+.ps +2
diff --git a/contrib/chem/examples/122/chBa_jump.chem b/contrib/chem/examples/122/chBa_jump.chem
new file mode 100644
index 00000000..9e60a28e
--- /dev/null
+++ b/contrib/chem/examples/122/chBa_jump.chem
@@ -0,0 +1,43 @@
+chBa_jump.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+SiO2 # name = SiO2
+move right 1
+CH3CH2NH2.HCl # name = CH3CH2NH2HCl
+
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chBb_bonds.chem b/contrib/chem/examples/122/chBb_bonds.chem
new file mode 100644
index 00000000..22fdf951
--- /dev/null
+++ b/contrib/chem/examples/122/chBb_bonds.chem
@@ -0,0 +1,44 @@
+chBb_bonds.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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/>.
+
+########################################################################
+
+C
+frontbond -170 from C ; H
+backbond 10 from C ; CO2H
+bond left length .15 from C ; H2N
+bond right from C ; CH3
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/chem/examples/122/chBc_rings.chem b/contrib/chem/examples/122/chBc_rings.chem
new file mode 100644
index 00000000..a6fff436
--- /dev/null
+++ b/contrib/chem/examples/122/chBc_rings.chem
@@ -0,0 +1,45 @@
+chBc_rings.chem:
+.br
+.cstart
+
+# Example file for `chem':
+
+# This originates from Computing Science Technical Report No. 122
+# CHEM - A Program for Typesetting Chemical Diagrams: User Manual
+# by Jon L. Bentley, Lynn W. Jelinski, Brian W. Kernighan
+# <http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz>.
+
+# Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+# 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
+ bond -120 from R1.V5 ; CH3O
+R2: ring4 pointing 45 with .V4 at R1.V2
+R3: aromatic ring6 put N at 4 put S at 2 at R2 + (.75,0)
+R4: ring5 pointing left at R3 + (.75,0)
+ label R4
+
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: Nroff
+# End:
+.cend
diff --git a/contrib/groffer/perl/README_PERL b/contrib/groffer/perl/README_PERL
new file mode 100644
index 00000000..0e58f06e
--- /dev/null
+++ b/contrib/groffer/perl/README_PERL
@@ -0,0 +1,263 @@
+README_PERL
+
+Special description for the Perl version of `groffer'
+
+The files related to the Perl version are
+
+perl/groffer.pl perl main source file for groffer
+perl/func.pl selection of functions needed for groffer.pl
+perl/man.pl selection of man functions needed for groffer.pl
+perl/split_env.sh shell script called from groffer.pl to split a variable
+perl/groffer.man manual file rewritten for the perl version of groffer
+perl/README_PERL this file
+perl_test.pl test whether perl has a suitable version
+version.sh information on version number and last update
+
+
+Compatibility
+
+This is the Perl version of groffer. It was written under Perl v5.8.8
+and needs an installed Perl version of at least version 5.6.1.
+
+It was written in Linux, but it seems to be independent of the
+operating system. At least no directory slashes are used.
+
+For testing, `groffer.pl' may be used directly without a Makefile. By
+`make' this file will be transformed into the file `groffer' that will
+be installed.
+
+The following options were removed compared to the shell version of
+groffer:
+
+--shell --debug-func --debug-not_func --debug-lm --debug-shell
+--debug-stacks --debug-user
+
+They can be used, but they are just ignored.
+
+Otherwise, the Perl version has the same functionality as the shell
+version.
+
+
+Temporary files
+
+The Perl version keeps more files for debug mode than the shell
+version. The `file' and `so' temporaries are numbered and the files
+with .so request are copied. All .so requests are handled; this is an
+extension to `man' that deals only with the first .so request.
+
+
+Comparison of variable names in both groffer versions
+
+shell perl
+=======================================================================
+$GROFFER_OPT $Env{GROFFER}
+$PATH @Path
+$_ADDOPTS_GROFF @Addopts_Groff
+$_ALL_PARAMS @ARGV
+$_APROPOS_PROG $Apropos_Prog
+$_APROPOS_SECTIONS $Opt{APROPOS_SECTIONS}
+$_AT $at
+$_AT_BINDIR_AT $at_at{BINDIR}
+$_AT_G_AT $at_at{G}
+$_AT_LIBDIR_AT $at_at{LIBDIR}
+$_BAD -
+$_BEFORE_MAKE $before_make
+$_CONF_FILES @Conf_Files
+$_CONF_FILE_ETC @Conf_Files
+$_CONF_FILE_HOME @Conf_Files
+$_DEBUG_FUNC_CHECK -
+$_DEBUG_KEEP_FILES @Debug{KEEP}
+$_DEBUG_LM -
+$_DEBUG_PRINT_FILENAMES @Debug{FILENAMES}
+$_DEBUG_PRINT_PARAMS @Debug{PARAMS}
+$_DEBUG_PRINT_SHELL -
+$_DEBUG_PRINT_TMPDIR @Debug{TMPDIR}
+$_DEBUG_STACKS -
+$_DEBUG_USER_WITH_STACK -
+$_DEFAULT_MODES $Default_Modes
+$_DEFAULT_RESOLUTION $Default_Resolution
+$_DEFAULT_TTY_DEVICE $Default_tty_Device
+$_DISPLAY_ARGS $Display{ARGS}
+$_DISPLAY_MODE $Display{MODE}
+$_DISPLAY_PROG $Display{PROG}
+$_ERROR -
+$_FILEARGS @Filespecs
+$_FILESPEC_ARG $Filespec_Arg
+$_FILESPEC_IS_MAN $Filespec_Is_Man
+$_FUNC_STACK -
+$_GOOD -
+$_GROFFER2_SH -
+$_GROFFER_LIBDIR $groffer_libdir
+$_GROFFER_SH _
+$_GROFF_VERSION $Groff_Version
+$_GROFF_VERSION_PRESET $groff_version_preset
+$_HAS_BZIP $Has_bzip
+$_HAS_COMPRESSION $Has_Compression
+$_LAST_UPDATE $last_update
+$_MACRO_PACKAGES $Macro_Packages
+$_MACRO_PKG $Macro_Pkg
+$_MANOPT_ALL -
+$_MANOPT_EXTENSION -
+$_MANOPT_LANG -
+$_MANOPT_PAGER -
+$_MANOPT_PATH -
+$_MANOPT_SEC -
+$_MANOPT_SYS -
+$_MAN_ALL $Man{ALL}
+$_MAN_AUTO_SEC_CHARS $Man{AUTO_SEC_CHARS}
+$_MAN_AUTO_SEC_LIST @{$Man{AUTO_SEC}}
+$_MAN_ENABLE $Man{ENABLE}
+$_MAN_EXT $Man{EXT}
+$_MAN_FORCE $Man{FORCE}
+$_MAN_IS_SETUP $Man{IS_SETUP}
+$_MAN_LANG $Man{LANG}
+$_MAN_LANG2 $Man{LANG2}
+$_MAN_PATH @{$Man{PATH}}
+$_MAN_SEC @{$Man{SEC}}
+$_MAN_SEC_CHARS $Man{SEC_CHARS}
+$_MAN_SEC_LIST -
+$_MAN_SYS @{$Man{SYS}}
+$_NO -
+$_NO_FILESPECS $No_Filespecs
+$_NULL_DEV $Dev_Null
+$_OK -
+$_OPTS_CMDLINE_LONG_ARG %Opts_Cmdline_Long with value 1
+$_OPTS_CMDLINE_LONG_NA %Opts_Cmdline_Long with value 0
+$_OPTS_CMDLINE_SHORT_ARG %Opts_Cmdline_Short with value 1
+$_OPTS_CMDLINE_SHORT_NA %Opts_Cmdline_Short with value 0
+$_OPTS_GROFFER_LONG_ARG -
+$_OPTS_GROFFER_LONG_NA -
+$_OPTS_GROFFER_SHORT_ARG -
+$_OPTS_GROFFER_SHORT_NA -
+$_OPTS_GROFF_LONG_ARG -
+$_OPTS_GROFF_LONG_NA -
+$_OPTS_GROFF_SHORT_ARG -
+$_OPTS_GROFF_SHORT_NA -
+$_OPTS_MANOPT_LONG_ARG -
+$_OPTS_MANOPT_LONG_NA -
+$_OPTS_MANOPT_SHORT_ARG -
+$_OPTS_MANOPT_SHORT_NA -
+$_OPTS_MAN_LONG_ARG -
+$_OPTS_MAN_LONG_NA -
+$_OPTS_MAN_SHORT_ARG -
+$_OPTS_MAN_SHORT_NA -
+$_OPTS_X_LONG_ARG -
+$_OPTS_X_LONG_NA -
+$_OPTS_X_SHORT_ARG -
+$_OPTS_X_SHORT_NA -
+$_OPT_ALL $Opt{ALL}
+$_OPT_APROPOS $Opt{APROPOS}
+$_OPT_BD $Opt{BD}
+$_OPT_BG $Opt{BG}
+$_OPT_BW $Opt{BW}
+$_OPT_DEFAULT_MODES $Opt{DEFAULT_MODES}
+$_OPT_DEVICE $Opt{DEVICE}
+$_OPT_DISPLAY $Opt{DISPLAY}
+$_OPT_DO_NOTHING $Opt{DO_NOTHING}
+$_OPT_EXTENSION $Opt{EXTENSION}
+$_OPT_FG $Opt{FG}
+$_OPT_FN $Opt{FN}
+$_OPT_GEOMETRY $Opt{GEOMETRY}
+$_OPT_ICONIC $Opt{ICONIC}
+$_OPT_LANG $Opt{LANG}
+$_OPT_MANPATH $Opt{MANPATH}
+$_OPT_MODE $Opt{MODE}
+$_OPT_PAGER $Opt{PAGER}
+$_OPT_RESOLUTION $Opt{RESOLUTION}
+$_OPT_RV $Opt{RV}
+$_OPT_SECTIONS $Opt{SECTIONS}
+$_OPT_SYSTEMS $Opt{SYSTEMS}
+$_OPT_TEXT_DEVICE $Opt{TEXT_DEVICE}
+$_OPT_TITLE $Opt{TITLE}
+$_OPT_V $Opt{V}
+$_OPT_VIEWER_DVI $Opt{VIEWER_DVI}
+$_OPT_VIEWER_HTML $Opt{VIEWER_HTML}
+$_OPT_VIEWER_PDF $Opt{VIEWER_PDF}
+$_OPT_VIEWER_PS $Opt{VIEWER_PS}
+$_OPT_VIEWER_X $Opt{VIEWER_X}
+$_OPT_WHATIS $Opt{WHATIS}
+$_OPT_XRM @{$Opt{XRM}}
+$_OPT_Z $Opt{Z}
+$_OUTPUT_FILE_NAME $Output_File_Name
+$_PDF_DID_NOT_WORK $PDF_Did_Not_Work
+$_PDF_HAS_GS $PDF_Has_gs
+$_PDF_HAS_PS2PDF $PDF_Has_ps2pdf
+$_PROCESS_ID -
+$_PROGRAM_VERSION $program_version
+$_REG_TITLE_LIST @Reg_Title
+$_SHELL -
+$_SP -
+$_SPACE_CASE -
+$_SPACE_SED -
+$_SPECIAL_FILESPEC $Special_Filespec
+$_SPECIAL_SETUP $Special_Setup
+$_SQ -
+$_START_DIR $Start_Dir
+$_TAB -
+$_TMP_CAT $fh_cat, $tmp_cat
+$_TMP_DIR $tmpdir
+$_TMP_MAN -
+$_TMP_MANSPEC $Manspec for @{Man{MANSPEC}{$Manspec}}
+$_TMP_STDIN $fh_stdin, $tmp_stdin
+$_UNSET -
+$_VIEWER_BACKGROUND $Viewer_Background
+$_VIEWER_DVI_TTY $Viewer_tty{'DVI'}
+$_VIEWER_DVI_X $Viewer_X{'DVI'}
+$_VIEWER_HTML_TTY $Viewer_tty{'HTML'}
+$_VIEWER_HTML_X $Viewer_X{'HTML'}
+$_VIEWER_PDF_TTY $Viewer_tty{'PDF'}
+$_VIEWER_PDF_X $Viewer_X{'PDF'}
+$_VIEWER_PS_TTY $Viewer_tty{'PS'}
+$_VIEWER_PS_X $Viewer_X{'PS'}
+$_VIEWER_TTY_TTY -
+$_VIEWER_TTY_X -
+$_VIEWER_X_TTY $Viewer_tty{'X'}
+$_VIEWER_X_X $Viewer_X{'X'}
+$_YES -
+$return_bad -
+$return_error -
+$return_good -
+$return_no -
+$return_ok -
+$return_var -
+$return_yes -
+- @ARGV
+- @Manopt
+- $Opt{LOCATION}
+- $Opt{X}
+- $File_Split_Env
+- @Options
+- @StartingARGV
+- @StartingConf
+- $Umask
+
+
+####### License
+
+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/>.
+
+Last update: 5 Jan 2009
+
+
+####### Emacs settings
+
+Local Variables:
+mode: text
+End:
diff --git a/contrib/groffer/perl/func.pl b/contrib/groffer/perl/func.pl
new file mode 100644
index 00000000..d0fc6399
--- /dev/null
+++ b/contrib/groffer/perl/func.pl
@@ -0,0 +1,789 @@
+#! /usr/bin/env perl
+
+# groffer - display groff files
+
+# Source file position: <groff-source>/contrib/groffer/perl/func.pl
+# Installed position: <prefix>/lib/groff/groffer/func.pl
+
+# 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 `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/>.
+
+########################################################################
+
+use strict;
+use warnings;
+
+########################################################################
+# some functions
+########################################################################
+
+##########
+# cat_z(<file>)
+#
+# Decompress or cat the <file>.
+#
+# Return: the decompressed file as array
+#
+sub cat_z {
+ my $n = @_;
+ die "cat_z(): one argument is needed; you used $n;"
+ unless $n == 1;
+
+ my $file = $_[0];
+ die "cat_z(): `$file' is not a readable file;" unless -f $file && -r $file;
+ return () if -z $file;
+
+ my @res;
+ if ($main::Has_Compression) {
+ if ($main::Has_bzip) {
+ # test whether bz2 compressed, shell return must be inverted
+ unless ( system("bzip2 -t $file 2>$main::Dev_Null") ) {
+ @res = `bzip2 -c -d $file 2>$main::Dev_Null`;
+ return @res;
+ }
+ # if not compressed with gz, gzip will act like `cat'
+ @res = `gzip -c -d -f $file 2>$main::Dev_Null`;
+ return @res;
+ }
+ } else {
+ my $fh;
+ open $fh, "<$file" or die "cat_z(): could not open $file";
+ @res = <$fh>;
+ close $fh;
+ return @res;
+ }
+ ();
+} # cat_z()
+
+
+##########
+# clean_up()
+#
+# Remove the temporary directory and restore the system.
+#
+sub clean_up {
+ umask $main::Umask;
+ chdir $main::Start_Dir;
+ if ($main::Debug{'KEEP'} && -d $main::tmpdir) {
+ my $glob = File::Spec->catfile($main::tmpdir, '*');
+ unlink glob($glob); # rm $tmpdir/*
+ rmdir $main::tmpdir;
+ }
+} # clean_up()
+
+
+##########
+# get_dirname(<path>)
+#
+# Split the path and return the directory name part
+#
+# Return: string of directory name
+#
+sub get_dirname {
+ my $n = @_;
+ die "get_filename(): one argument is needed; you used $n;" unless $n == 1;
+ return '' unless $_[0];
+
+ my ($dirname, $filename) = &split_path($_[0]);
+ $dirname;
+} # get_dirname()
+
+
+##########
+# get_filename(<path>)
+#
+# Split the path and return the file name part
+#
+# Return: string of file name
+#
+sub get_filename {
+ my $n = @_;
+ die "get_dirname(): one argument is needed; you used $n;" unless $n == 1;
+ return '' unless $_[0];
+
+ my ($dirname, $filename) = &split_path($_[0]);
+ $filename;
+} # get_filename()
+
+
+##########
+# is_X()
+#
+# Test whether X Windows is running.
+#
+sub is_X {
+ return 1 if $ENV{'DISPLAY'};
+ return 0;
+} # is_X()
+
+
+##########
+# list_has(<list_ref>, <string>)
+#
+# Determine if <list_ref> has <string> as element.
+#
+sub list_has {
+ my $n = @_;
+ die "list_has(): 2 arguments are needed; you used $n;"
+ unless $n == 2;
+
+ my $list_ref = $_[0];
+ my $string = $_[1];
+ die "list_has(): first argument must be an array reference;"
+ unless ref($list_ref) eq 'ARRAY';
+
+ foreach ( @$list_ref ) {
+ return 1 if $_ eq $string;
+ }
+ 0;
+}
+
+
+##########
+# path_uniq(<dir>...)
+#
+# make path having unique existing directories
+#
+sub path_uniq {
+ my @a;
+ my %h;
+ foreach (@_) {
+ next if exists $h{$_};
+ next unless -d $_;
+ push @a, $_;
+ $h{$_} = 1;
+ }
+ @a;
+} # path_uniq()
+
+
+##########
+# 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 "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 "empty hash\n";
+ return 1;
+ }
+ print "hash (ignore the ^ characters):\n";
+ for my $k (sort keys %$hr) {
+ my $hk = $hr->{$k};
+ print " $k => ";
+ if (defined $hk) {
+ print "^$hk^";
+ } else {
+ print "undef";
+ }
+ print "\n";
+ }
+
+ 1;
+} # print_hash()
+
+
+##########
+# print_times(<string>)
+#
+# print the time, result: user, system, child process user, child system
+#
+sub print_times {
+ my @t = times;
+ my $s = '';
+ $s = $_[0] if $_[0];
+# print STDERR "$s: @t\n";
+} # print_times()
+
+BEGIN { &print_times("start"); }
+END { &print_times("end"); }
+
+
+##########
+# split_path(<path>)
+#
+# Split the path into directory and file name parts
+#
+# Return: array with 2 elements consisting of directory and file name
+#
+sub split_path {
+ my $n = @_;
+ die "split_path(): one argument is needed; you used $n;" unless $n == 1;
+ my $arg = $_[0];
+ return () unless $arg;
+
+ my $basename = basename($arg);
+ if ( $basename ne $arg ) { # path with dir
+ # fileparse() is from File::Basename
+ my($filename, $dirname, $suffix) = fileparse($arg);
+ return ($dirname, $basename);
+ }
+ return ('', $arg);
+}
+
+
+{
+ my $nr_file = 0;
+ my $nr_so = 0;
+
+ my $tmp_file_base;
+ my $tmp_so_base;
+
+ my $soelim_r = '';
+ $soelim_r = '-r'
+ if ! system("echo -n '' | soelim -r 2>$main::Dev_Null >$main::Dev_Null");
+
+ ##########
+ # to_tmp (<filename>)
+ #
+ # Print file (decompressed) to the temporary cat file with handling .SO
+ # for man pages.
+ #
+ sub to_tmp {
+ my $n = @_;
+ die "to_tmp(): one argument is needed; you used $n;"
+ unless $n == 1;
+
+ my $arg = $_[0];
+ return 1 unless $arg;
+ die "to_tmp(): $arg is not an existing file;" unless -f $arg;
+ die "to_tmp(): could not read file $arg;" unless -r $arg;
+ return 1 if -z $arg;
+
+ $tmp_file_base = File::Spec->catfile($main::tmpdir, ',file')
+ unless $tmp_file_base;
+ $tmp_so_base = File::Spec->catfile($main::tmpdir, ',so')
+ unless $tmp_so_base;
+
+ open $main::fh_cat, ">>$main::tmp_cat" or
+ die "to_tmp(): could not open temporary cat file";
+
+ if ($main::Opt{'WHATIS'}) {
+ &whatis_filename($arg);
+ return 1;
+ }
+
+ ### to_tmp()
+ my $dir = &get_dirname($arg);
+
+ my ($fh_file, $tmp_file, $fh_tmp, $tmp_tmp);
+ ++$nr_file;
+ $tmp_file = $tmp_file_base . $nr_file;
+ $tmp_tmp = File::Spec->catfile($main::tmpdir, ',tmp');
+
+ print STDERR "file: $arg\n" if $main::Debug{'FILENAMES'};
+
+ if ($main::Filespec_Is_Man) {
+ my ($fh_so, $tmp_so);
+
+ open $fh_file, ">$tmp_file" or
+ die "to_tmp(): could not open $tmp_file;";
+ foreach ( &cat_z($arg) ) {
+ print $fh_file "$_";
+ }
+ close $fh_file;
+
+ open $fh_file, "<$tmp_file" or
+ die "to_tmp(): could not open $tmp_file;";
+ my @list;
+ foreach (<$fh_file>) {
+ if (/^[\.']\s*so\s/) {
+ chomp;
+ s/^[\.']\s*so\s*//;
+ push @list, $_;
+ }
+ }
+ close $fh_file;
+
+ if ( @list && $main::Debug{'KEEP'} ) {
+ my $f = $tmp_file . '+man';
+ copy($tmp_file, $f);
+ }
+
+ ### to_tmp()
+ DO_MAN_SO: foreach (@list) {
+ # start of _do_man_so() in shell version
+ my $so = $_;
+ my $soname = $so;
+ $soname =~ s/\\\s/ /g;
+
+ my $sofound;
+ my $path = File::Spec->rootdir();
+ if ($soname =~ m#^$path#) { # absolute path name
+ next DO_MAN_SO if -f $soname;
+ foreach ('.gz', '.Z', '.bz2') {
+ my $name = $soname . $_;
+ if (-f $name) {
+ $sofound = $name;
+ last;
+ }
+ } # foreach
+ next DO_MAN_SO unless $sofound;
+ } else { # relative to man path
+ LOOP: foreach my $ext ('', '.gz', '.Z', '.bz2') {
+ foreach my $p ( @{$main::Man{'PATH'}} ) {
+ my $f = File::Spec->catfile($p, "$soname$ext");
+ if (-f $f) {
+ $sofound = $f if -f $f;
+ last LOOP;
+ }
+ } # foreach
+ } # LOOP:
+ next DO_MAN_SO unless $sofound;
+ } # if on path
+
+ print STDERR "file from .so: $so\n" if $main::Debug{'FILENAMES'};
+
+ ### to_tmp()
+ ++$nr_so;
+ $tmp_so = $tmp_so_base . $nr_so;
+ unlink $tmp_so if -e $tmp_so;
+ open $fh_so, ">$tmp_so" or
+ die "to_tmp(): could not open $tmp_so;";
+ foreach ( &cat_z($sofound) ) {
+ print $fh_so $_;
+ }
+ close $fh_so;
+
+ my $esc = $so;
+ $esc =~ s/\\/\\\\/g;
+ open $fh_file, "<$tmp_file" or
+ die "to_tmp(): could not open $tmp_file;";
+ open $fh_tmp, ">$tmp_tmp" or
+ die "to_tmp(): could not open $tmp_tmp;";
+ foreach (<$fh_file>) {
+ s#^([\.'])\s*so\s+($so|$esc|$soname)\s*\n$#${1}so $tmp_so\n#s;
+ print $fh_tmp $_;
+ }
+ ### to_tmp()
+ close $fh_tmp;
+ close $fh_file;
+ unlink $tmp_file if -e $tmp_file;
+ rename $tmp_tmp, $tmp_file;
+ # end of _do_man_so() in shell version
+ } # foreach (@list)
+
+ if ( @list && $main::Debug{'KEEP'} ) {
+ my $f = $tmp_file . '+tmp';
+ copy($tmp_file, $f);
+ }
+
+ unlink $tmp_tmp if -e $tmp_tmp;
+ rename $tmp_file, $tmp_tmp;
+ system("soelim -I$dir $soelim_r $tmp_tmp >$tmp_file");
+ unlink $tmp_tmp if -e $tmp_tmp;
+
+ } else { # $Filespec_Is_Man is empty
+ open $fh_tmp, ">$tmp_tmp" or
+ die "to_tmp(): could not open $tmp_tmp;";
+ foreach (cat_z $arg) {
+ print $fh_tmp $_;
+ }
+ close $fh_tmp;
+ if ($dir) {
+ system("soelim -I$dir $soelim_r $tmp_tmp >$tmp_file");
+ } else {
+ system("soelim $soelim_r $tmp_tmp >$tmp_file");
+ }
+ unlink $tmp_tmp;
+ } # if ($Filespec_Is_Man)
+
+ ### to_tmp()
+ my $grog = `grog $tmp_file`;
+ die "to_tmp(): grog error on $tmp_file;" if $?;
+ chomp $grog;
+ print STDERR "grog output: $grog\n" if $main::Debug{'GROG'};
+ if ($grog =~ /^.*\s-m.*$/) {
+ $grog =~ s/\s+/ /g;
+ $grog =~ s/ -m / -m/g;
+ $grog =~ s/ -mm([^ ]) / -m$1/g;
+ foreach my $g (split / /, $grog) {
+ if ($g =~ /^-m/) {
+ my $ref = \@main::Macro_Packages;
+ if ( &list_has($ref, $g) ) {
+ if (! $main::Macro_Pkg) {
+ $main::Macro_Pkg = $g;
+ } elsif ($main::Macro_Pkg eq $g) {
+ 1;
+ } elsif ($main::Macro_Pkg =~ /^-m/) {
+ warn "to_tmp(): Ignore $arg because it needs $g " .
+ "instead of $main::Macro_Pkg";
+ unlink $tmp_file unless $main::Debug{'KEEP'};
+ return 0;
+ } elsif ($main::Macro_Pkg ne $g) {
+ die "to_tmp(): \$Macro_Pkg does not start with -m: " .
+ "$main::Macro_Pkg";
+ } # if (! $main::Macro_Pkg)
+ } # if (&list_has
+ } # if (/^-m/)
+ } # foreach my $g
+ } # if $grog
+
+ open $fh_file, "<$tmp_file" or
+ die "to_tmp(): could not open $tmp_file for reading;";
+ open $main::fh_cat, ">>$main::tmp_cat" or
+ die "to_tmp(): could not open $main::tmp_cat for appending;";
+ foreach (<$fh_file>) {
+ print $main::fh_cat $_;
+ }
+ close $main::fh_cat;
+ close $fh_file;
+
+ unless ( $main::Debug{'KEEP'} ) {
+ unlink $tmp_file;
+ foreach ( glob("$tmp_so_base*") ) {
+ unlink $_;
+ }
+ }
+ 1;
+ } # to_tmp()
+}
+
+##########
+# to_tmp_line (<text>...)
+#
+# Print array of lines with <text> to the temporary cat file. \n is added
+# if a line does not end with \n.
+#
+sub to_tmp_line {
+ my $n = @_;
+ return 1 if $n == 0;
+ open $main::fh_cat, ">>$main::tmp_cat" or
+ die "to_tmp_line(): could not open temporary cat file";
+ foreach (@_) {
+ my $line = $_;
+ chomp($line);
+ print $main::fh_cat "$line\n";
+ }
+ close $main::fh_cat;
+ 1;
+} # to_tmp_line()
+
+
+##########
+# usage()
+#
+# Print usage information for --help.
+#
+sub usage {
+ print "\n";
+ &version();
+ print <<EOF;
+
+Usage: groffer [option]... [filespec]...
+
+Display roff files, standard input, and/or Unix manual pages with an X
+Window viewer or in several text modes. All input is decompressed
+on-the-fly with all formats that gzip can handle.
+
+"filespec" is one of
+ "filename" name of a readable file
+ "-" for standard input
+ "man:name(n)" man page "name" in section "n"
+ "man:name.n" man page "name" in section "n"
+ "man:name" man page "name" in first section found
+ "name(n)" man page "name" in section "n"
+ "name.n" man page "name" in section "n"
+ "n name" man page "name" in section "n"
+ "name" man page "name" in first section found
+where `section' is a single character out of [1-9on], optionally followed
+by some more letters that are called the `extension'.
+
+-h --help print this usage message.
+-T --device=name pass to groff using output device "name".
+-v --version print version information.
+-V display the groff execution pipe instead of formatting.
+-X display with "gxditview" using groff -X.
+-Z --ditroff --intermediate-output
+ generate groff intermediate output without
+ post-processing and viewing, like groff -Z.
+All other short options are interpreted as "groff" formatting options.
+
+The most important groffer long options are
+
+--apropos=name start man's "apropos" program for "name".
+--apropos-data=name
+ "apropos" for "name" in man's data sections 4, 5, 7.
+--apropos-devel=name
+ "apropos" for "name" in development sections 2, 3, 9.
+--apropos-progs=name
+ "apropos" for "name" in man's program sections 1, 6, 8.
+--auto choose mode automatically from the default mode list.
+--default reset all options to the default value.
+--default-modes=mode1,mode2,...
+ set sequence of automatically tried modes.
+--dvi display in a viewer for TeX device independent format.
+--dvi-viewer=prog choose the viewer program for dvi mode.
+--groff process like groff, disable viewing features.
+--help display this helping output.
+--html display in a web browser.
+--html-viewer=program
+ choose the web browser for html mode.
+--man check file parameters first whether they are man pages.
+--mode=auto|dvi|groff|html|pdf|ps|source|text|tty|www|x|X
+ choose display mode.
+--no-man disable man-page facility.
+--no-special disable --all, --apropos*, and --whatis
+--pager=program preset the paging program for tty mode.
+--pdf display in a PDF viewer.
+--pdf-viewer=prog choose the viewer program for pdf mode.
+--ps display in a Postscript viewer.
+--ps-viewer=prog choose the viewer program for ps mode.
+--source output as roff source.
+--text output in a text device without a pager.
+--to-stdout output the content of the mode file without display.
+--tty display with a pager on text terminal even when in X.
+--tty-viewer=prog select a pager for tty mode; same as --pager.
+--whatis display the file name and description of man pages
+--www same as --html.
+--www-viewer=prog same as --html-viewer
+--x --X display with "gxditview" using an X* device.
+--x-viewer=prog choose viewer program for x mode (X mode).
+--X-viewer=prog same as "--xviewer".
+
+The usual X Windows toolkit options transformed into GNU long options:
+--background=color, --bd=size, --bg=color, --bordercolor=color,
+--borderwidth=size, --bw=size, --display=Xdisplay, --fg=color,
+--fn=font, --font=font, --foreground=color, --geometry=geom, --iconic,
+--resolution=dpi, --rv, --title=text, --xrm=resource
+
+Long options of GNU "man":
+--all, --ascii, --ditroff, --extension=suffix, --locale=language,
+--local-file=name, --location, --manpath=dir1:dir2:...,
+--sections=s1:s2:..., --systems=s1,s2,..., --where, ...
+
+Development options that are not useful for normal usage:
+--debug, --debug-filenames, --debug-grog, --debug-keep, --debug-params,
+--debug-tmpdir, --do-nothing, --print=text
+
+EOF
+} # usage()
+
+
+##########
+# version()
+#
+# Get version information from version.sh and print a text with this.
+#
+sub version {
+ my $groff_version;
+ my $program_version = '';
+ my $last_update = '';
+ my $groff_version_preset = '';
+
+ die "$main::File_version_sh does not exist;"
+ unless -f "$main::File_version_sh";
+ my $fh;
+ open $fh, "<$main::File_version_sh";
+ foreach (<$fh>) {
+ chomp;
+ if (/^\s*_PROGRAM_VERSION\s*=\s*['"]*([^'"]*)['"]*\s*;?\s*$/) {
+ $program_version = $1;
+ next;
+ }
+ if (/^\s*_LAST_UPDATE\s*=\s*['"]*([^'"]*)['"]*\s*;?\s*$/) {
+ $last_update = $1;
+ next;
+ }
+ if (/^\s*_GROFF_VERSION_PRESET\s*=\s*['"]*([^'"]*)['"]*\s*;?\s*$/) {
+ # this setting of the groff version is only used before make is run,
+ # otherwise @VERSION@ will set it, see groffer.sh.
+ $groff_version_preset = $1;
+ next;
+ }
+ }
+ close $fh;
+
+ if ($main::Groff_Version) {
+ $groff_version = $main::Groff_Version;
+ } else {
+ $groff_version = $groff_version_preset;
+ }
+ my $year = $last_update;
+ $year =~ s/^.* //;
+ print <<EOF;
+groffer $program_version of $last_update (Perl version)
+is part of groff version $groff_version.
+Copyright (C) $year Free Software Foundation, Inc.
+GNU groff and groffer 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()
+
+
+##########
+# where_is_prog(<program>)
+#
+# Test whether <program> without its arguments exists or is a program
+# in $PATH.
+#
+# Arguments : 1, <program> can have spaces and arguments.
+# Return : a hash with `dir', `file', `fullname', `args' if
+# argument exists or is a program in $PATH, empty hash else.
+#
+sub where_is_prog {
+ scalar @_ eq 1 or die "where_is_prog(): only one argument is allowed";
+ my $p1 = $_[0];
+ return () unless $p1;
+
+ $p1 =~ s/\s+/ /g;
+ $p1 =~ s/(\\)+ / /g;
+ $p1 =~ s/^ | $//g;
+ return () unless $p1;
+
+ my $noarg = $p1;
+ $noarg =~ s/ -.*$//;
+ return () unless $noarg;
+
+ my $args;
+ if ($p1 =~ /^.* -.*$/) {
+ $args = $p1;
+ $args =~ s#^$noarg ##;
+ }
+ $args = '' unless defined $args;
+
+ my %result;
+
+ # test whether $noarg has directory, so it is not tested with $PATH
+ my ($dir, $name) = &split_path($noarg);
+ $result{'dir'} = $dir;
+
+### where_is_prog()
+ if (-f $noarg && -x $noarg) {
+ $result{'args'} = $args;
+ $result{'file'} = $name;
+ $result{'fullname'} = File::Spec->catfile($dir, $name);
+ return %result;
+ }
+
+ if ($dir) { # $noarg has name with directory
+ # now $wip_noarg (with directory) is not an executable file
+
+ # test name with space
+ if ($name =~ / /) {
+ my @base = split(/ /, $name);
+ my $n = pop @base;
+ my @baseargs = ($n);
+ while (@base) {
+ my $base = join(' ', @base);
+ my $file = File::Spec->catpath($dir, $base);
+ if (-f $file && -x $file) {
+ my $baseargs = join(' ', @baseargs);
+ ### where_is_prog()
+ if ($args) {
+ $args = "$baseargs $args";
+ } else {
+ $args = $baseargs;
+ }
+ $result{'args'} = $args;
+ $result{'file'} = $base;
+ $result{'fullname'} = $file;
+ return %result;
+ } # file test $file
+ $n = pop @base;
+ unshift(@baseargs, $n);
+ } # while (@base)
+ } # end of test name with space
+ return ();
+ } # test on $dir
+
+ # now $noarg doesn't have a directory part
+
+ $name = $noarg;
+
+ # check with $PATH
+
+ # test path with $win_noarg as a whole, evt. with spaces
+ foreach my $d (@main::Path) {
+ my $file = File::Spec->catfile($d, $name);
+ if (-f $file && -x $file) {
+ $result{'args'} = $args;
+ $result{'fullname'} = $file;
+ ($result{'dir'}, $result{'file'}) = &split_path($file);
+ return %result;
+ } # file test $file
+ } # foreach (@main::Path)
+
+### where_is_prog()
+ if ($name =~ / /) {
+ my @base = split(/ /, $name);
+ my $n = pop @base;
+ my @baseargs = ($n);
+ while (@base) {
+ my $base = join(' ', @base);
+ foreach my $d (@maon::Path) {
+ my $file = File::Spec->catfile($d, $base);
+ if (-f $file && -x $file) {
+ my $baseargs = join(' ', @baseargs);
+ if ($args) {
+ $args = "$baseargs $args";
+ } else {
+ $args = $baseargs;
+ }
+ $result{'args'} = $args;
+ $result{'fullname'} = $file;
+ ($result{'dir'}, $result{'file'}) = &split_path($file);
+ return %result;
+ } # file test $file
+ } # foreach (@main::Path)
+ $n = pop @base;
+ unshift(@baseargs, $n);
+ } # while (@base)
+ } # test $name on space
+ return ();
+} # where_is_prog()
+
+
+##########
+# wait()
+#
+# stop for checking temp files, etc.
+#
+sub wait {
+ print "push Ctrl-D";
+ my @x = <STDIN>;
+ print "\n";
+} # wait()
+
+1;
diff --git a/contrib/groffer/perl/groffer.man b/contrib/groffer/perl/groffer.man
new file mode 100644
index 00000000..fcef1cde
--- /dev/null
+++ b/contrib/groffer/perl/groffer.man
@@ -0,0 +1,3920 @@
+.TH GROFFER @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@"
+.SH NAME
+groffer \- display groff files and man\~pages on X and tty
+.
+.SH "SYNOPSIS"
+.\" The .SH was moved to this place in order to appease `apropos'.
+.
+.\" --------------------------------------------------------------------
+.\" Legalese
+.\" --------------------------------------------------------------------
+.
+.de author
+This file was written by Bernd Warken <groff-bernd.warken-72@web.de>.
+..
+.de copyleft
+Copyright (C) 2001, 2002, 2004-2006, 2009-2012
+ 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 3 of the License, 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 visit
+.nh
+.B <http://www.gnu.org/licenses/>.
+.hy
+..
+.
+.\" --------------------------------------------------------------------
+.\" Setup
+.\" --------------------------------------------------------------------
+.
+.ds Ellipsis "\&.\|.\|.\&\"
+.
+.\" --------------------------------------------------------------------
+.\" Macro definitions
+.
+.\" --------------------------------------------------------------------
+.\" .CB (<text>...)
+.\"
+.\" Print in constant-width bold font.
+.\"
+.de CB
+. ft CB
+. Text \\$*
+. ft
+..
+.\" --------------------------------------------------------------------
+.\" .CI (<text>...)
+.\"
+.\" Print in constant-width italic font.
+.\"
+.de CI
+. ft CI
+. Text \\$*
+. ft
+..
+.\" --------------------------------------------------------------------
+.\" .CR (<text>...)
+.\"
+.\" Print in constant-width roman font.
+.\"
+.de CR
+. ft CR
+. Text \\$*
+. ft
+..
+.\" --------------------------------------------------------------------
+.\" .Error (<text>...)
+.\"
+.\" Print error message to terminal and abort.
+.\"
+.de Error
+. tm \\$*
+. ab
+..
+.\" --------------------------------------------------------------------
+.\" .Env_var (<env_var_name> [<punct>])
+.\"
+.\" Display an environment variable, with optional punctuation.
+.\"
+.de Env_var
+. nh
+. SM
+. Text \f[CB]\\$1\f[]\\$2
+. hy
+..
+.\" --------------------------------------------------------------------
+.\" .File_name (<path_name>)
+.\"
+.\" Display a file or directory name in CB font.
+.\"
+.de File_name
+. Header_CB \\$@
+..
+.\" --------------------------------------------------------------------
+.\" .Header_CB (<path_name>)
+.\"
+.\" Display a line in CB font, for example after .TP
+.\"
+.de Header_CB
+. nh
+. Text \f[CB]\\$1\f[]\\$2
+. hy
+..
+.\" --------------------------------------------------------------------
+.\" .Text (<text>...)
+.\"
+.\" Treat the arguments as text, no matter how they look.
+.\"
+.de Text
+. if \\n[.$]=0 \
+. return
+. nh
+. nop \)\\$*\)
+. hy
+..
+.\" --------------------------------------------------------------------
+.\" .Topic ([<indent>])
+.\"
+.\" A bulleted paragraph
+.\"
+.de Topic
+. ie \\n[.$]=0 \
+. ds @indent 2m\"
+. el \
+. ds @indent \\$1\"
+. IP \[bu] \\*[@indent]
+. rm @indent
+..
+
+.\" End of macro definitions
+.
+.
+.\" --------------------------------------------------------------------
+.\" SH "SYNOPSIS"
+.\" --------------------------------------------------------------------
+.
+.SY groffer
+.OP option \*[Ellipsis]
+.OP --
+.OP \%filespec \*[Ellipsis]
+.YS
+.
+.SY groffer
+.BR -h | --help
+.YS
+.
+.SY groffer
+.BR -v | --version
+.YS
+.
+.
+.\" --------------------------------------------------------------------
+.SH DESCRIPTION
+.\" --------------------------------------------------------------------
+.
+The
+.B \%groffer
+program is the easiest way to use
+.BR \%groff (@MAN1EXT@).
+It can display arbitrary documents written in the
+.I \%groff
+language, see
+.BR \%groff (@MAN7EXT@),
+or other
+.I \%roff
+languages, see
+.BR \%roff (@MAN7EXT@),
+that are compatible to the original
+.I \%troff
+language.
+.
+It finds and runs all necessary
+.I groff
+preprocessors, such as
+.BR @g@chem .
+.
+.
+.P
+The
+.B \%groffer
+program also includes many of the features for finding and displaying
+the \%\f[CR]Unix\f[] manual pages
+.nh
+.RI ( man\~pages ),
+.hy
+such that it can be used as a replacement for a
+.BR \%man (1)
+program.
+.
+Moreover, compressed files that can be handled by
+.BR \%gzip (1)
+or
+.BR \%bzip2 (1)
+are decompressed on-the-fly.
+.
+.
+.P
+The normal usage is quite simple by supplying a file name or name of a
+.I \%man\~page
+without further options.
+.
+But the option handling has many possibilities for creating special
+behaviors.
+.
+This can be done either in configuration files, with the shell
+environment variable
+.Env_var \%$GROFFER_OPT ,
+or on the command line.
+.
+.
+.P
+The output can be generated and viewed in several different ways
+available for
+.IR \%groff .
+.
+This includes the
+.I \%groff
+native \%\f[CR]X\~Window\f[] viewer
+.BR \%gxditview (@MAN1EXT@),
+each
+.IR \%Postcript ,
+.IR \%pdf ,
+or
+.I \%dvi
+display program, a web browser by generating
+.I \%html
+in
+.IR \%www\~mode ,
+or several
+.I \%text\~modes
+in text terminals.
+.
+.
+.P
+Most of the options that must be named when running
+.B \%groff
+directly are determined automatically for
+.BR \%groffer ,
+due to the internal usage of the
+.BR \%grog (@MAN1EXT@)
+program.
+.
+But all parts can also be controlled manually by arguments.
+.
+.
+.P
+Several file names can be specified on the command line arguments.
+.
+They are transformed into a single document in the normal way of
+.BR \%groff .
+.
+.
+.P
+Option handling is done in \f[CR]GNU\f[] style.
+.
+Options and file names can be mixed freely.
+.
+The option
+.RB ` \-\- '
+closes the option handling, all following arguments are treated as
+file names.
+.
+Long options can be abbreviated in several ways.
+.
+.
+.\" --------------------------------------------------------------------
+.SH "OPTION OVERVIEW"
+.\" --------------------------------------------------------------------
+.
+.TP
+.I breaking options
+.RS
+.P
+.SY
+.OP -h\~\fR|\fB\~--help
+.OP -v\~\fR|\fB\~--version
+.YS
+.RE
+.
+.
+.TP
+.I \%groffer mode options
+.RS
+.P
+.SY
+.OP --auto
+.OP --default
+.OP --default\-modes mode1,mode2,\*[Ellipsis]
+.OP --dvi
+.OP --dvi\-viewer prog
+.OP --groff
+.OP --html
+.OP --html\-viewer prog
+.OP --mode display_mode
+.OP --pdf
+.OP --pdf\-viewer prog
+.OP --ps
+.OP --ps\-viewer prog
+.OP --source
+.OP --text
+.OP --to\-stdout
+.OP --tty
+.OP --tty\-viewer prog
+.OP --www
+.OP --www\-viewer prog
+.OP --x\~\fR|\fB\~--X
+.OP --x\-viewer\~\fR|\fB\~--X\-viewer prog
+.YS
+.RE
+.
+.
+.TP
+.I options related to \%groff
+.RS
+.P
+.SY
+.OP -T\~\fR|\fB\~--device device
+.OP -Z\~\fR|\fB\~--intermediate\-output\~\fR|\fB\~--ditroff
+.YS
+.P
+All further
+.B \%groff
+short options are accepted.
+.RE
+.
+.
+.TP
+.I options for man\~pages
+.RS
+.P
+.SY
+.OP --apropos
+.OP --apropos\-data
+.OP --apropos\-devel
+.OP --apropos\-progs
+.OP --man
+.OP --no\-man
+.OP --no\-special
+.OP --whatis
+.YS
+.RE
+.
+.
+.TP
+.I long options taken over from GNU man
+.RS
+.P
+.SY
+.OP --all
+.OP --ascii
+.OP --ditroff
+.OP --extension suffix
+.OP --locale language
+.OP --local\-file
+.OP --location\~\fR|\fB\~--where
+.OP --manpath dir1:dir2:\*[Ellipsis]
+.OP --no\-location
+.OP --pager program
+.OP --sections sec1:sec2:\*[Ellipsis]
+.OP --systems sys1,sys2,\*[Ellipsis]
+.OP --troff\-device device
+.YS
+.P
+Further long options of \f[CR]GNU\f[]
+.B man
+are accepted as well.
+.RE
+.
+.
+.TP
+.I X Window Toolkit options
+.RS
+.P
+.SY
+.OP --bd\~\fR|\fB\~--bordercolor pixels
+.OP --bg\~\fR|\fB\~--background color
+.OP --bw\~\fR|\fB\~--borderwidth pixels
+.OP --display X-display
+.OP --fg\~\fR|\fB\~--foreground color
+.OP --fn\~\fR|\fB\~--ft\~\fR|\fB\~--font font_name
+.OP --geometry size_pos
+.OP --resolution value
+.OP --rv
+.OP --title string
+.OP --xrm X\-resource
+.YS
+.RE
+.
+.
+.TP
+.I options for development
+.RS
+.P
+.SY
+.OP --debug
+.OP --debug\-filenames
+.OP --debug\-grog
+.OP --debug\-keep
+.OP --debug\-params
+.OP --debug\-tmpdir
+.OP --do\-nothing
+.OP --print text
+.OP -V
+.YS
+.RE
+.
+.
+.TP
+.I \%filespec arguments
+.RS
+.P
+The
+.I \%filespec
+parameters are all arguments that are neither an option nor an option
+argument.
+.
+They usually mean a file name or a
+.I man page
+searching scheme.
+.
+.
+.P
+In the following, the term
+.I section_extension
+is used.
+.
+It means a word that consists of a
+.I man section
+that is optionally followed by an
+.IR extension .
+.
+The name of a
+.I man section
+is a single character from
+.BR \%[1-9on] ,
+the
+.I extension
+is some word.
+.
+The
+.I extension
+is mostly lacking.
+.
+.
+.P
+No
+.I \%filespec
+parameters means standard input.
+.
+.
+.TP 10m
+.B -
+stands for standard input (can occur several times).
+.
+.
+.TP
+.I filename
+the path name of an existing file.
+.
+.
+.TP
+.BI man: name ( section_extension )
+.TQ
+.BI man: name . section_extension
+.TQ
+.IB name ( section_extension )
+.TQ
+.IB name . section_extension
+.TQ
+.I "section_extension name"
+search the \%man\~page
+.I \%name
+in the section with optional extension
+.IR section_extension .
+.
+.
+.TP
+.BI man: name
+\%man\~page in the lowest
+.I \%man\~section
+that has
+.IR \%name .
+.
+.
+.TP
+.I name
+if
+.I \%name
+is not an existing file search for the man\~page
+.I \%name
+in the lowest man\~section.
+.
+.RE
+.
+.
+.\" --------------------------------------------------------------------
+.SH "OPTION DETAILS"
+.\" --------------------------------------------------------------------
+.
+The
+.B \%groffer
+program can usually be run with very few options.
+.
+But for special purposes, it supports many options.
+.
+These can be classified in 5 option classes.
+.
+.
+.P
+All short options of
+.B \%groffer
+are compatible with the short options of
+.BR \%groff (@MAN1EXT@).
+.
+All long options of
+.B \%groffer
+are compatible with the long options of
+.BR \%man (1).
+.
+.
+.P
+Arguments for long option names can be abbreviated in several ways.
+.
+First, the argument is checked whether it can be prolonged as is.
+.
+Furthermore, each minus sign
+.B -
+is considered as a starting point for a new abbreviation.
+.
+This leads to a set of multiple abbreviations for a single argument.
+.
+For example,
+.B --de\-n\-f
+can be used as an abbreviation for
+.BR --debug\-not\-func ,
+but
+.B --de\-n
+works as well.
+.
+If the abbreviation of the argument leads to several resulting options
+an error is raised.
+.
+.
+.P
+These abbreviations are only allowed in the environment variable
+.Env_var \%$GROFFER_OPT ,
+but not in the configuration files.
+.
+In configuration, all long options must be exact.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "groffer breaking Options"
+.\" --------------------------------------------------------------------
+.
+As soon as one of these options is found on the command line it is
+executed, printed to standard output, and the running
+.B \%groffer
+is terminated thereafter.
+.
+All other arguments are ignored.
+.
+.
+.TP
+.B -h\~\fR|\fB\~--help
+Print help information with a short explanation of options to
+standard output.
+.
+.
+.TP
+.B -v\~\fR|\fB\~--version
+Print version information to standard output.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "groffer Mode Options"
+.\" --------------------------------------------------------------------
+.
+The display mode and the viewer programs are determined by these
+options.
+.
+If none of these mode and viewer options is specified
+.B \%groffer
+tries to find a suitable display mode automatically.
+.
+The default modes are
+.IR "mode pdf" ,
+.IR "mode ps" ,
+.IR "mode html" ,
+.IR "mode x" ,
+and
+.I "mode dvi"
+in \%\f[CR]X\~Window\f[] with different viewers and
+.I mode tty
+with device
+.I latin1
+under
+.B less
+on a terminal; other modes are tested if the programs for the main
+default mode do not exist.
+.
+.
+.P
+In \%\f[CR]X\~Window\f[],
+many programs create their own window when called.
+.B \%groffer
+can run these viewers as an independent program in the background.
+.
+As this does not work in text mode on a terminal (tty) there must be a
+way to know which viewers are \%\f[CR]X\~Window\f[] graphical
+programs.
+.
+The
+.B \%groffer
+script has a small set of information on some viewer names.
+.
+If a viewer argument of the command\-line chooses an element that is
+kept as \%\f[CR]X\~Window\f[] program in this list it is treated as a
+viewer that can run in the background.
+.
+All other, unknown viewer calls are not run in the background.
+.
+.
+.P
+For each mode, you are free to choose whatever viewer you want.
+.
+That need not be some graphical viewer suitable for this mode.
+.
+There is a chance to view the output source; for example, the
+combination of the options
+.B --mode=ps
+and
+.B --ps\-viewer=less
+shows the content of the
+.I Postscript
+output, the source code, with the pager
+.BR less .
+.
+.
+.TP
+.B --auto
+Equivalent to
+.BR --mode=auto .
+.
+.
+.TP
+.B --default
+Reset all configuration from previously processed command line options
+to the default values.
+.
+This is useful to wipe out all former options of the configuration, in
+.Env_var \%$GROFFER_OPT ,
+and restart option processing using only the rest of the command line.
+.
+.
+.TP
+.BI --default\-modes \ mode1,mode2,\*[Ellipsis]
+Set the sequence of modes for
+.I \%auto\~mode
+to the comma separated list given in the argument.
+.
+See
+.B --mode
+for details on modes. Display in the default manner; actually, this
+means to try the modes
+.IR x ,
+.IR ps ,
+and
+.I \%tty
+in this sequence.
+.
+.
+.
+.TP
+.B --dvi
+Equivalent to
+.BR --mode=\%dvi .
+.
+.
+.TP
+.BI --dvi\-viewer \ prog
+Choose a viewer program for
+.IR \%dvi\~mode .
+.
+This can be a file name or a program to be searched in
+.Env_var $PATH .
+.
+Known \%\f[CR]X\~Window\f[]
+.I \%dvi
+viewers include
+.BR \%xdvi (1)
+and
+.BR \%dvilx (1).
+.
+In each case, arguments can be provided additionally.
+.
+.
+.TP
+.B --groff
+Equivalent to
+.BR --mode=groff .
+.
+.
+.TP
+.B --html
+Equivalent to
+.BR --mode=html .
+.
+.
+.TP
+.B --html\-viewer
+Choose a web browser program for viewing in
+.IR \%html\~mode .
+.
+It can be the path name of an executable file or a program in
+.Env_var $PATH .
+.
+In each case, arguments can be provided additionally.
+.
+.
+.TP
+.BI --mode \ value
+.
+Set the display mode.
+.
+The following mode values are recognized:
+.
+.RS
+.
+.TP
+.Header_CB auto
+Select the automatic determination of the display mode.
+.
+The sequence of modes that are tried can be set with the
+.B --default\-modes
+option.
+.
+Useful for restoring the
+.I \%default\~mode
+when a different mode was specified before.
+.
+.
+.TP
+.Header_CB dvi
+Display formatted input in a
+.I \%dvi
+viewer program.
+.
+By default, the formatted input is displayed with the
+.BR \%xdvi (1)
+program.
+.
+.
+.TP
+.Header_CB groff
+After the file determination, switch
+.B \%groffer
+to process the input like
+.BR \%groff (@MAN1EXT@)
+would do.
+.
+This disables the
+.I \%groffer
+viewing features.
+.
+.
+.TP
+.Header_CB html
+Translate the input into html format and display the result in a web
+browser program.
+.
+By default, the existence of a sequence of standard web browsers is
+tested, starting with
+.BR \%konqueror (1)
+and
+.BR \%mozilla (1).
+The text html viewer is
+.BR \%lynx (1).
+.
+.
+.TP
+.Header_CB pdf
+Display formatted input in a
+.I \%PDF
+(Portable Document Format) viewer
+program.
+.
+By default, the input is formatted by
+.B \%groff
+using the Postscript device, then it is transformed into the PDF file
+format using
+.BR \%gs (1),
+or
+.BR ps2pdf (1).
+If that's not possible, the
+.I Postscript mode (ps)
+is used instead.
+.
+Finally it is displayed using different viewer programs.
+.
+.I \%pdf
+has a big advantage because the text is displayed graphically and
+is searchable as well.
+.
+.
+.TP
+.Header_CB ps
+Display formatted input in a Postscript viewer program.
+.
+By default, the formatted input is displayed in one of many viewer
+programs.
+.
+.
+.TP
+.Header_CB text
+Format in a
+.I \%groff\~text\~mode
+and write the result to standard output without a pager or viewer
+program.
+.
+The text device,
+.I \%latin1
+by default, can be chosen with option
+.BR -T .
+.
+.
+.TP
+.Header_CB tty
+Format in a
+.I \%groff\~text\~mode
+and write the result to standard output using a text pager program,
+even when in \%\f[CR]X\~Window\f[].
+.
+.
+.TP
+.Header_CB www
+Equivalent to
+.BR --mode=html .
+.
+.
+.TP
+.Header_CB x
+Display the formatted input in a native
+.I roff
+viewer.
+.
+By default, the formatted input is displayed with the
+.BR \%gxditview (@MAN1EXT@)
+program being distributed together with
+.BR \%groff .
+But the standard \%\f[CR]X\~Window\f[] tool
+.BR \%xditview (1)
+can also be chosen with the option
+.BR --x\-viewer .
+The default resolution is
+.BR 75dpi ,
+but
+.B 100dpi
+are also possible.
+.
+The default
+.I groff
+device
+for the resolution of
+.B 75dpi
+is
+.BR X75\-12 ,
+for
+.B 100dpi
+it is
+.BR X100 .
+.
+The corresponding
+.I "groff intermediate output"
+for the actual device is generated and the result is displayed.
+.
+For a resolution of
+.BR 100dpi ,
+the default width of the geometry of the display program is chosen to
+.BR 850dpi .
+.
+.
+.TP
+.Header_CB X
+Equivalent to
+.BR --mode=x .
+.
+.
+.P
+The following modes do not use the
+.I \%groffer
+viewing features.
+.
+They are only interesting for advanced applications.
+.
+.
+.TP
+.Header_CB groff
+Generate device output with plain
+.I \%groff
+without using the special viewing features of
+.IR \%groffer .
+If no device was specified by option
+.B -T
+the
+.I \%groff
+default
+.B \%ps
+is assumed.
+.
+.
+.TP
+.Header_CB source
+Output the roff source code of the input files without further
+processing.
+.
+.
+.RE
+.
+.
+.TP
+.B --pdf
+Equivalent to
+.BR --mode=pdf .
+.
+.
+.TP
+.BI --pdf\-viewer \ prog
+Choose a viewer program for
+.IR \%pdf\~mode .
+.
+This can be a file name or a program to be searched in
+.Env_var $PATH ;
+arguments can be provided additionally.
+.
+.
+.TP
+.B --ps
+Equivalent to
+.BR --mode=ps .
+.
+.
+.TP
+.BI --ps\-viewer \ prog
+Choose a viewer program for
+.IR \%ps\~mode .
+.
+This can be a file name or a program to be searched in
+.Env_var $PATH .
+.
+Common Postscript viewers include
+.BR \%gv (1),
+.BR \%ghostview (1),
+and
+.BR \%gs (1),
+.
+In each case, arguments can be provided additionally.
+.
+.
+.TP
+.B --source
+Equivalent to
+.BR --mode=source .
+.
+.
+.TP
+.B --text
+Equivalent to
+.BR --mode=text .
+.
+.
+.TP
+.B --to\-stdout
+The file for the chosen mode is generated and its content is printed
+to standard output.
+.
+It will not be displayed in graphical mode.
+.
+.
+.TP
+.B --tty
+Equivalent to
+.BR --mode=tty .
+.
+.
+.TP
+.BI --tty\-viewer \ prog
+Choose a text pager for mode
+.IR tty .
+The standard pager is
+.BR less (1).
+This option is equivalent to
+.I man
+option
+.BR --pager=\fIprog\fP .
+The option argument can be a file name or a program to be searched in
+.Env_var $PATH ;
+arguments can be provided additionally.
+.
+.
+.TP
+.B --www
+Equivalent to
+.BR --mode=html .
+.
+.
+.TP
+.BI --www\-viewer \ prog
+Equivalent to
+.BR --html\-viewer .
+.
+.
+.TP
+.B --X\~\fR|\fB\~--x
+Equivalent to
+.BR --mode=x .
+.
+.
+.TP
+.BI --X\-viewer\~\fR|\fB\~--x\-viewer \ prog
+Choose a viewer program for
+.IR \%x\~mode .
+Suitable viewer programs are
+.BR \%gxditview (@MAN1EXT@)
+which is the default and
+.BR \%xditview (1).
+The argument can be any executable file or a program in
+.Env_var $PATH ;
+arguments can be provided additionally.
+.
+.
+.TP
+.B --
+Signals the end of option processing; all remaining arguments are
+interpreted as
+.I \%filespec
+parameters.
+.
+.
+.P
+Besides these,
+.B \%groffer
+accepts all short options that are valid for the
+.BR \%groff (@MAN1EXT@)
+program.
+.
+All
+.RB \%non- groffer
+options are sent unmodified via
+.B \%grog
+to
+.BR \%groff .
+.
+So postprocessors, macro packages, compatibility with
+.I classical
+.IR \%troff ,
+and much more can be manually specified.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Options related to groff"
+.\" --------------------------------------------------------------------
+.
+All short options of
+.B \%groffer
+are compatible with the short options of
+.BR \%groff (@MAN1EXT@).
+.
+The following of
+.B \%groff
+options have either an additional special meaning within
+.B \%groffer
+or make sense for normal usage.
+.
+.
+.P
+Because of the special outputting behavior of the
+.B \%groff
+option
+.B -Z
+.B \%groffer
+was designed to be switched into
+.IR \%groff\~mode ;
+the
+.I \%groffer
+viewing features are disabled there.
+.
+The other
+.B \%groff
+options do not switch the mode, but allow to customize the formatting
+process.
+.
+.
+.TP
+.B --a
+This generates an ascii approximation of output in the
+.IR \%text\~modes .
+.
+That could be important when the text pager has problems with control
+sequences in
+.IR "tty mode" .
+.
+.
+.TP
+.BI --m \ file
+Add
+.I \%file
+as a
+.I \%groff
+macro file.
+.
+This is useful in case it cannot be recognized automatically.
+.
+.
+.TP
+.BI --P \ opt_or_arg
+Send the argument
+.I \%opt_or_arg
+as an option or option argument to the actual
+.B \%groff
+postprocessor.
+.
+.
+.TP
+.B --T \fIdevname\fR\~\fR|\fB\~--device \fIdevname\fR
+.
+This option determines
+.BR \%groff 's
+output device.
+.
+The most important devices are the text output devices for referring
+to the different character sets, such as
+.BR \%ascii ,
+.BR \%utf8 ,
+.BR \%latin1 ,
+and others.
+.
+Each of these arguments switches
+.B \%groffer
+into a
+.I \%text\~mode
+using this device, to
+.I \%mode\~tty
+if the actual mode is not a
+.IR \%text\~mode .
+.
+The following
+.I \%devname
+arguments are mapped to the corresponding
+.B \%groffer
+.B --mode=\fIdevname\fR
+option:
+.BR \%dvi ,
+.BR \%html ,
+and
+.BR \%ps .
+All
+.B \%X*
+arguments are mapped to
+.IR \%mode\~x .
+Each other
+.I \%devname
+argument switches to
+.I \%mode\~groff
+using this device.
+.
+.
+.TP
+.B --X
+is equivalent to
+.BR "groff \-X" .
+It displays the
+.I groff intermediate output
+with
+.BR gxditview .
+As the quality is relatively bad this option is deprecated; use
+.B --X
+instead because the
+.I \%x\~mode
+uses an
+.IR X *
+device for a better display.
+.
+.
+.TP
+.B -Z\~\fR|\fB\~--intermediate-output\~\fR|\fB\~--ditroff
+Switch into
+.I \%groff\~mode
+and format the input with the
+.I \%groff intermediate output
+without postprocessing; see
+.BR \%groff_out (@MAN5EXT@).
+This is equivalent to option
+.B --ditroff
+of
+.IR \%man ,
+which can be used as well.
+.
+.
+.P
+All other
+.B \%groff
+options are supported by
+.BR \%groffer ,
+but they are just transparently transferred to
+.B \%groff
+without any intervention.
+.
+The options that are not explicitly handled by
+.B \%groffer
+are transparently passed to
+.BR \%groff .
+.
+Therefore these transparent options are not documented here, but in
+.BR \%groff (@MAN1EXT@).
+Due to the automatism in
+.BR \%groffer ,
+none of these
+.B \%groff
+options should be needed, except for advanced usage.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Options for man\~pages"
+.\" --------------------------------------------------------------------
+.
+.TP
+.B --apropos
+Start the
+.BR \%apropos (1)
+command or facility of
+.BR \%man (1)
+for searching the
+.I \%filespec
+arguments within all
+.I \%man\~page
+descriptions.
+.
+Each
+.I \%filespec
+argument is taken for search as it is;
+.I section
+specific parts are not handled, such that
+.B 7 groff
+searches for the two arguments
+.B 7
+and
+.BR groff ,
+with a large result; for the
+.I \%filespec
+.B groff.7
+nothing will be found.
+.
+The
+.I language
+locale is handled only when the called programs do support this; the
+GNU
+.B apropos
+and
+.B man \-k
+do not.
+.
+The display differs from the
+.B \%apropos
+program by the following concepts:
+.RS
+.Topic
+Construct a
+.I \%groff
+frame similar to a
+.I \%man\~page
+to the output of
+.BR \%apropos ,
+.Topic
+each
+.I \%filespec
+argument is searched on its own.
+.Topic
+The restriction by
+.B --sections
+is handled as well,
+.Topic
+wildcard characters are allowed and handled without a further option.
+.RE
+.
+.
+.TP
+.B --apropos\-data
+Show only the
+.B \%apropos
+descriptions for data documents, these are the
+.BR \%man (7)
+.IR sections\~4 ", " 5 ", and " 7 .
+.
+Direct
+.I section
+declarations are ignored, wildcards are accepted.
+.
+.
+.TP
+.B --apropos\-devel
+Show only the
+.B \%apropos
+descriptions for development documents, these are the
+.BR man (7)
+.IR sections\~2 ", " 3 ", and " 9 .
+.
+Direct
+.I section
+declarations are ignored, wildcards are accepted.
+.
+.
+.TP
+.B --apropos\-progs
+Show only the
+.B \%apropos
+descriptions for documents on programs, these are the
+.BR \%man (7)
+.IR sections\~1 ", " 6 ", and " 8 .
+.
+Direct
+.I section
+declarations are ignored, wildcards are accepted.
+.
+.
+.TP
+.B --whatis
+For each
+.I \%filespec
+argument search all
+.I \%man\~pages
+and display their description \[em] or say that it is not a
+.IR \%man\~page .
+This is written from anew, so it differs from
+.IR man 's
+.B whatis
+output by the following concepts
+.RS
+.Topic
+each retrieved file name is added,
+.Topic
+local files are handled as well,
+.Topic
+the \fIlanguage\fP and \fIsystem\fP locale is supported,
+.Topic
+the display is framed by a
+.I groff
+output format similar to a
+.IR \%man\~page ,
+.Topic
+wildcard characters are allowed without a further option.
+.RE
+.
+.
+.P
+The following options were added to
+.B \%groffer
+for choosing whether the file name arguments are interpreted as names
+for local files or as a search pattern for
+.IR \%man\~pages .
+.
+The default is looking up for local files.
+.
+.
+.TP
+.B --man
+Check the non-option command line arguments
+.nh
+.RI ( filespecs )
+.hy
+first on being
+.IR \%man\~pages ,
+then whether they represent an existing file.
+.
+By default, a
+.I \%filespec
+is first tested whether it is an existing file.
+.
+.
+.TP
+.B --no-man\~\fR|\fB\~--local-file
+Do not check for
+.IR \%man\~pages .
+.
+.B --local-file
+is the corresponding
+.B man
+option.
+.
+.
+.TP
+.B --no-special
+Disable former calls of
+.BR --all ,
+.BR --apropos* ,
+and
+.BR --whatis .
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Long options taken over from GNU man"
+.\" --------------------------------------------------------------------
+.
+The long options of
+.B \%groffer
+were synchronized with the long options of \f[CR]GNU\f[]
+.BR man .
+.
+All long options of \f[CR]GNU\f[]
+.B man
+are recognized, but not all of these options are important to
+.BR \%groffer ,
+so most of them are just ignored.
+.
+These ignored
+.B man
+options are
+.BR --catman ,
+.BR --troff ,
+and
+.BR --update .
+.
+.
+.P
+In the following, the
+.B man
+options that have a special meaning for
+.B \%groffer
+are documented.
+.
+.
+.P
+If your system has \f[CR]GNU\f[]
+.B man
+installed the full set of long and short options of the \f[CR]GNU\f[]
+.B man
+program can be passed via the environment variable
+.Env_var \%$MANOPT ;
+see
+.BR \%man (1).
+.
+.
+.TP
+.B --all
+In searching
+.IR \%man\~pages ,
+retrieve all suitable documents instead of only one.
+.
+.
+.TP
+.B -7\~\fR|\fB\~--ascii
+In
+.IR \%text\~modes ,
+display ASCII translation of special characters for critical environment.
+.
+This is equivalent to
+.BR "groff \%-mtty_char" ;
+see
+.BR groff_tmac (@MAN5EXT@).
+.
+.
+.TP
+.B --ditroff
+Produce
+.IR "groff intermediate output" .
+This is equivalent to
+.B \%groffer
+.BR -Z .
+.
+.
+.TP
+.BI --extension \ suffix
+Restrict
+.I \%man\~page
+search to file names that have
+.I \%suffix
+appended to their section element.
+.
+For example, in the file name
+.I \%/usr/share/man/man3/terminfo.3ncurses.gz
+the
+.I \%man\~page
+extension is
+.IR \%ncurses .
+.
+.
+.TP
+.BI --locale \ language
+.
+Set the language for
+.IR \%man\~pages .
+.
+This has the same effect, but overwrites
+.Env_var $LANG .
+.
+.
+.TP
+.B --location
+Print the location of the retrieved files to standard error.
+.
+.
+.TP
+.B --no-location
+Do not display the location of retrieved files; this resets a former
+call to
+.BR --location .
+.
+This was added by
+.BR \%groffer .
+.
+.
+.TP
+.BI --manpath \ 'dir1:dir2:\*[Ellipsis]'
+Use the specified search path for retrieving
+.I \%man\~pages
+instead of the program defaults.
+.
+If the argument is set to the empty string "" the search for
+.I \%man\~page
+is disabled.
+.
+.
+.TP
+.B --pager
+Set the pager program in
+.IR \%tty\~mode ;
+default is
+.BR \%less .
+This is equivalent to
+.BR --tty\-viewer .
+.
+.
+.TP
+.BI --sections \ sec1:sec2:\*[Ellipsis]
+Restrict searching for
+.I \%man\~pages
+to the given
+.IR sections ,
+a colon-separated list.
+.
+.
+.TP
+.BI --systems \ sys1,sys2,\*[Ellipsis]
+Search for
+.I \%man\~pages
+for the given operating systems; the argument
+.I \%systems
+is a comma-separated list.
+.
+.
+.TP
+.B --where
+Equivalent to
+.BR --location .
+.
+.
+.\" --------------------------------------------------------------------
+.SS "X\~\%Window\~\%Toolkit Options"
+.\" --------------------------------------------------------------------
+.
+The following long options were adapted from the corresponding
+\%\f[CR]X\~Window\~Toolkit\f[] options.
+.
+.B \%groffer
+will pass them to the actual viewer program if it is an
+\%\f[CR]X\~Window\f[] program.
+.
+Otherwise these options are ignored.
+.
+.
+.P
+Unfortunately these options use the old style of a single minus for
+long options.
+.
+For
+.B \%groffer
+that was changed to the standard with using a double minus for long
+options, for example,
+.B \%groffer
+uses the option
+.B --font
+for the \%\f[CR]X\~Window\f[] option
+.BR -font .
+.
+.
+.P
+See
+.BR X (7)
+and the documentation on the \%\f[CR]X\~Window\~Toolkit\f[] options
+for more details on these options and their arguments.
+.
+.
+.TP
+.BI --background \ color
+Set the background color of the viewer window.
+.
+.
+.TP
+.BI --bd \ pixels
+This is equivalent to
+.BR --bordercolor .
+.
+.
+.TP
+.BI --bg \ color
+This is equivalent to
+.BR --background .
+.
+.
+.TP
+.BI --bw \ pixels
+This is equivalent to
+.BR --borderwidth .
+.
+.
+.TP
+.BI --bordercolor \ pixels
+Specifies the color of the border surrounding the viewer window.
+.
+.
+.TP
+.BI --borderwidth \ pixels
+Specifies the width in pixels of the border surrounding the viewer
+window.
+.
+.
+.TP
+.BI --display \ X-display
+Set the \%\f[CR]X\~Window\f[] display on which the viewer program
+shall be started, see the \%\f[CR]X\~Window\f[] documentation for the
+syntax of the argument.
+.
+.
+.TP
+.BI --foreground \ color
+Set the foreground color of the viewer window.
+.
+.
+.TP
+.BI --fg \ color
+This is equivalent to
+.BR -foreground .
+.
+.
+.TP
+.BI --fn \ font_name
+This is equivalent to
+.BR --font .
+.
+.
+.TP
+.BI --font \ font_name
+Set the font used by the viewer window.
+.
+The argument is an \%\f[CR]X\~Window\f[] font name.
+.
+.
+.TP
+.BI --ft \ font_name
+This is equivalent to
+.BR --font .
+.
+.
+.TP
+.BI --geometry \ size_pos
+Set the geometry of the display window, that means its size and its
+starting position.
+.
+See
+.BR \%X (7)
+for the syntax of the argument.
+.
+.
+.TP
+.BI --resolution \ value
+Set \%\f[CR]X\~Window\f[] resolution in dpi (dots per inch) in some
+viewer programs.
+.
+The only supported dpi values are
+.B 75
+and
+.BR 100 .
+.
+Actually, the default resolution for
+.B \%groffer
+is set to
+.BR 75dpi .
+The resolution also sets the default device in
+.IR "mode x" .
+.
+.
+.TP
+.B --rv
+Reverse foreground and background color of the viewer window.
+.
+.
+.TP
+.BI --title "\ 'some text'"
+Set the title for the viewer window.
+.
+.
+.TP
+.BI --xrm \ 'resource'
+Set \f[CR]\%X\~Window\f[] resource.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Options for Development"
+.\" --------------------------------------------------------------------
+.
+.TP
+.B --debug
+Enable all debugging options
+.BR --debug\-\fItype\fP .
+.
+The temporary files are kept and not deleted, the
+.B grog
+output is printed, the name of the temporary directory is printed, the
+displayed file names are printed, and the parameters are printed.
+.
+.
+.TP
+.B --debug\-filenames
+Print the names of the files and
+.I \%man\~pages
+that are displayed by
+.BR \&groffer .
+.
+.
+.TP
+.B --debug\-grog
+Print the output of all
+.B grog
+commands.
+.
+.
+.TP
+.B --debug\-keep
+Enable two debugging informations.
+.
+Print the name of the temporary directory and keep the temporary
+files, do not delete them during the run of
+.BR \%groffer .
+.
+.
+.TP
+.B --debug\-params
+Print the parameters, as obtained from the configuration files, from
+.Env_var \%GROFFER_OPT ,
+and the command line arguments.
+.
+.
+.TP
+.B --debug\-tmpdir
+Print the name of the temporary directory.
+.
+.
+.TP
+.B --do-nothing
+This is like
+.BR --version ,
+but without the output; no viewer is started.
+.
+This makes only sense in development.
+.
+.
+.TP
+.B --print=\fItext\fR
+Just print the argument to standard error.
+.
+This is good for parameter check.
+.
+.
+.TP
+.B -V
+This is an advanced option for debugging only.
+.
+Instead of displaying the formatted input, a lot of
+.I \%groffer
+specific information is printed to standard output:
+.
+.RS
+.Topic
+the output file name in the temporary directory,
+.
+.Topic
+the display mode of the actual
+.B \%groffer
+run,
+.
+.Topic
+the display program for viewing the output with its arguments,
+.
+.Topic
+the active parameters from the config files, the arguments in
+.Env_var \%$GROFFER_OPT ,
+and the arguments of the command line,
+.
+.Topic
+the pipeline that would be run by the
+.B \%groff
+program, but without executing it.
+.RE
+.
+.
+.P
+Other useful debugging options are the
+.B \%groff
+option
+.B -Z
+and
+.BR --mode=groff .
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Filespec Arguments"
+.\" --------------------------------------------------------------------
+.
+A
+.I \%filespec
+parameter is an argument that is not an option or option argument.
+.
+In
+.BR \%groffer ,
+.I \%filespec
+parameters are a file name or a template for searching
+.IR \%man\~pages .
+.
+These input sources are collected and composed into a single output
+file such as
+.B \%groff
+does.
+.
+.
+.P
+The strange \%\f[CR]POSIX\f[] behavior to regard all arguments behind
+the first non-option argument as
+.I \%filespec
+arguments is ignored.
+.
+The \f[CR]GNU\f[] behavior to recognize options even when mixed with
+.I \%filespec
+arguments is used throughout.
+.
+But, as usual, the double minus argument
+.B --
+ends the option handling and interprets all following arguments as
+.I \%filespec
+arguments; so the \%\f[CR]POSIX\f[] behavior can be easily adopted.
+.
+.
+.P
+The options
+.B --apropos*
+have a special handling of
+.I filespec
+arguments.
+.
+Each argument is taken as a search scheme of its own.
+.
+Also a regexp (regular expression) can be used in the filespec.
+.
+For example,
+.B groffer --apropos '^gro.f$'
+searches
+.B groff
+in the
+.I man\~page
+name, while
+.B groffer --apropos groff
+searches
+.B groff
+somewhere in the name or description of the
+.IR man\~pages .
+.
+.
+.P
+All other parts of
+.IR groffer ,
+such as the normal display or the output with
+.B --whatis
+have a different scheme for
+.IR filespecs .
+No regular expressions are used for the arguments.
+.
+The
+.I filespec
+arguments are handled by the following scheme.
+.
+.
+.P
+It is necessary to know that on each system the
+.I \%man\~pages
+are sorted according to their content into several sections.
+.
+The
+.I classical man sections
+have a single-character name, either a digit from
+.B 1
+to
+.B 9
+or one of the characters
+.B n
+or
+.BR o .
+.
+.
+.P
+This can optionally be followed by a string, the so-called
+.IR extension .
+The
+.I extension
+allows to store several
+.I man\~pages
+with the same name in the same
+.IR section .
+But the
+.I extension
+is only rarely used, usually it is omitted.
+.
+Then the
+.I extensions
+are searched automatically by alphabet.
+.
+.
+.P
+In the following, we use the name
+.I section_extension
+for a word that consists of a single character
+.I section
+name or a
+.I section
+character that is followed by an
+.IR extension .
+.
+Each
+.I \%filespec
+parameter can have one of the following forms in decreasing sequence.
+.
+.
+.Topic
+No
+.I \%filespec
+parameters means that
+.B \%groffer
+waits for standard input.
+.
+The minus option
+.B -
+always stands for standard input; it can occur several times.
+.
+If you want to look up a
+.I \%man\~page
+called
+.B -
+use the argument
+.BR man:\- .
+.
+.
+.Topic
+Next a
+.I \%filespec
+is tested whether it is the path name of an existing file.
+.
+Otherwise it is assumed to be a searching pattern for a
+.IR \%man\~page .
+.
+.
+.Topic
+.BI \%man: name ( section_extension ) ,
+.BI \%man: name . section_extension,
+.IB \%name ( section_extension ) ,
+or
+.IB \%name . section_extension
+search the \%man\~page
+.I \%name
+in \%man\~section and possibly extension of
+.IR \%section_extension .
+.
+.
+.Topic
+Now
+.BI \%man: name
+searches for a
+.I \%man\~page
+in the lowest
+.I \%man\~section
+that has a document called
+.IR \%name .
+.
+.
+.Topic
+.I \%section_extension\~name
+is a pattern of 2 arguments that originates from a strange argument
+parsing of the
+.B man
+program.
+.
+Again, this searches the man page
+.I name
+with
+.IR \%section_extension ,
+a combination of a
+.I section
+character optionally followed by an
+.IR extension .
+.
+.
+.Topic
+We are left with the argument
+.I \%name
+which is not an existing file.
+.
+So this searches for the
+.I \%man\~page
+called
+.I \%name
+in the lowest
+.I \%man\~section
+that has a document for this name.
+.
+.
+.P
+Several file name arguments can be supplied.
+.
+They are mixed by
+.B \%groff
+into a single document.
+.
+Note that the set of option arguments must fit to all of these file
+arguments.
+.
+So they should have at least the same style of the
+.I \%groff
+language.
+.
+.
+.\" --------------------------------------------------------------------
+.SH "OUTPUT MODES"
+.\" --------------------------------------------------------------------
+.
+By default, the
+.B \%groffer
+program collects all input into a single file, formats it with the
+.B \%groff
+program for a certain device, and then chooses a suitable viewer
+program.
+.
+The device and viewer process in
+.B \%groffer
+is called a
+.IR \%mode .
+.
+The mode and viewer of a running
+.B \%groffer
+program is selected automatically, but the user can also choose it
+with options.
+.
+.
+The modes are selected by option the arguments of
+.BR --mode=\fIanymode .
+Additionally, each of this argument can be specified as an option of
+its own, such as
+.BR anymode .
+Most of these modes have a viewer program, which can be chosen by an
+option that is constructed like
+.BR --\fIanymode\fR\-viewer .
+.
+.
+.P
+Several different modes are offered, graphical modes for
+\f[CR]\%X\~Window\f[],
+.IR \%text\~modes ,
+and some direct
+.I \%groff\~modes
+for debugging and development.
+.
+.
+.P
+By default,
+.B \%groffer
+first tries whether
+.I \%x\~mode
+is possible, then
+.IR \%ps\~mode ,
+and finally
+.IR \%tty\~mode .
+.
+This mode testing sequence for
+.I \%auto\~mode
+can be changed by specifying a comma separated list of modes with the
+option
+.B --default\-modes.
+.
+.
+.P
+The searching for
+.I \%man\~pages
+and the decompression of the input are active in every mode.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Graphical Display Modes"
+.\" --------------------------------------------------------------------
+.
+The graphical display modes work mostly in the \%\f[CR]X\~Window\f[]
+environment (or similar implementations within other windowing
+environments).
+.
+The environment variable
+.Env_var \%$DISPLAY
+and the option
+.B --display
+are used for specifying the \%\f[CR]X\~Window\f[] display to be used.
+.
+If this environment variable is empty
+.B \%groffer
+assumes that no \%\f[CR]X\~Window\f[] is running and changes to a
+.IR \%text\~mode .
+.
+You can change this automatic behavior by the option
+.BR --default\-modes .
+.
+.
+.P
+Known viewers for the graphical display modes and their standard
+\%\f[CR]X\~Window\f[] viewer programs are
+.
+.Topic
+in a PDF viewer
+.nh
+.RI ( \%pdf\~mode )
+.hy
+.
+.Topic
+in a web browser
+.nh
+.RI ( html
+or
+.IR \%www\~mode )
+.hy
+.RE
+.
+.Topic
+in a Postscript viewer
+.nh
+.RI ( \%ps\~mode )
+.hy
+.
+.Topic
+\%\f[CR]X\~Window\f[]
+.I roff
+viewers such as
+.BR \%gxditview (@MAN1EXT@)
+or
+.BR \%xditview (1)
+(in
+.IR \%x\~mode )
+.
+.Topic
+in a dvi viewer program
+.nh
+.RI ( \%dvi\~mode )
+.hy
+.
+.
+.P
+The
+.I \%pdf\~mode
+has a major advantage \[em] it is the only graphical display mode that
+allows to search for text within the viewer; this can be a really
+important feature.
+.
+Unfortunately, it takes some time to transform the input into the PDF
+format, so it was not chosen as the major mode.
+.
+.
+.P
+These graphical viewers can be customized by options of the
+\%\f[CR]X\~Window\~Toolkit\f[].
+.
+But the
+.B \%groffer
+options use a leading double minus instead of the single minus used by
+the \%\f[CR]X\~Window\~Toolkit\f[].
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Text modes"
+.\" --------------------------------------------------------------------
+.
+There are two modes for text output,
+.I \%mode\~text
+for plain output without a pager and
+.I \%mode\~tty
+for a text output on a text terminal using some pager program.
+.
+.
+.P
+If the variable
+.Env_var \%$DISPLAY
+is not set or empty,
+.B \%groffer
+assumes that it should use
+.IR \%tty\~\%mode .
+.
+.
+.P
+In the actual implementation, the
+.I groff
+output device
+.I \%latin1
+is chosen for
+.IR \%text\~modes .
+.
+This can be changed by specifying option
+.B -T
+or
+.BR \%--device .
+.
+.
+.P
+The pager to be used can be specified by one of the options
+.B --pager
+and
+.BR --tty\-viewer ,
+or by the environment variable
+.Env_var \%$PAGER .
+If all of this is not used the
+.BR \%less (1)
+program with the option
+.B -r
+for correctly displaying control sequences is used as the default
+pager.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Special Modes for Debugging and Development"
+.\" --------------------------------------------------------------------
+.
+These modes use the
+.I \%groffer
+file determination and decompression.
+.
+This is combined into a single input file that is fed directly into
+.B \%groff
+with different strategy without the
+.I \%groffer
+viewing facilities.
+.
+These modes are regarded as advanced, they are useful for debugging
+and development purposes.
+.
+.
+.P
+The
+.I \%source\~mode
+with option
+.B --source
+just displays the decompressed input.
+.
+.
+.P
+Otion
+.B --to\-stdout
+does not display in a graphical mode.
+.
+It just generates the file for the chosen mode and then prints its
+content to standard output.
+.
+.
+.P
+The
+.I \%groff\~mode
+passes the input to
+.B \%groff
+using only some suitable options provided to
+.BR \%groffer .
+.
+This enables the user to save the generated output into a file or pipe
+it into another program.
+.
+.
+.P
+In
+.IR \%groff\~\%mode ,
+the option
+.B -Z
+disables post-processing, thus producing the
+.nh
+.I groff intermediate
+.IR output .
+.hy
+.
+In this mode, the input is formatted, but not postprocessed; see
+.BR \%groff_out (@MAN5EXT@)
+for details.
+.
+.
+.P
+All
+.B \%groff
+short options are supported by
+.BR \%groffer .
+.
+.
+.\" --------------------------------------------------------------------
+.SH "MAN PAGE SEARCHING"
+.\" --------------------------------------------------------------------
+.
+The default behavior of
+.B \%groffer
+is to first test whether a file parameter represents a local file; if
+it is not an existing file name, it is assumed to represent the name
+of a
+.IR \%man\~page .
+The following options can be used to determine whether the arguments
+should be handled as file name or
+.I \%man\~page
+arguments.
+.
+.TP
+.B --man
+forces to interpret all file parameters as
+.I \%filespecs
+for searching
+.IR \%man\~pages .
+.
+.TP
+.B --no\-man
+.TQ
+.B --local\-file
+disable the
+.I man
+searching; so only local files are displayed.
+.
+.
+.P
+If neither a local file nor a
+.I \%man\~page
+was retrieved for some file parameter a warning is issued on standard
+error, but processing is continued.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Search Algorithm"
+.\" --------------------------------------------------------------------
+.
+Let us now assume that a
+.I \%man\~page
+should be searched.
+.
+The
+.B \%groffer
+program provides a search facility for
+.IR \%man\~pages .
+.
+All long options, all environment variables, and most of the
+functionality of the \f[CR]GNU\fP
+.BR \%man (1)
+program were implemented.
+.
+The search algorithm shall determine which file is displayed for a given
+.IR \%man\~page .
+The process can be modified by options and environment variables.
+.
+.
+.P
+The only
+.I man
+action that is omitted in
+.B \%groffer
+are the preformatted
+.IR \%man\~pages ,
+also called
+.IR cat\~pages .
+.
+With the excellent performance of the actual computers, the
+preformatted
+.I \%man\~pages
+aren't necessary any longer.
+.
+Additionally,
+.B \%groffer
+is a
+.I roff
+program; it wants to read
+.I roff
+source files and format them itself.
+.
+.
+.P
+The algorithm for retrieving the file for a
+.I \%man\~page
+needs first a set of directories.
+.
+This set starts with the so-called
+.I man\~path
+that is modified later on by adding names of
+.I operating system
+and
+.IR language .
+.
+This arising set is used for adding the section directories which
+contain the
+.I \%man\~page
+files.
+.
+.
+.P
+The
+.I man\~path
+is a list of directories that are separated by colon.
+.
+It is generated by the following methods.
+.
+.Topic
+The environment variable
+.Env_var \%$MANPATH
+can be set.
+.
+.Topic
+It can be read from the arguments of the environment variable
+.Env_var \%$MANOPT .
+.
+.Topic
+The
+.I man\~path
+can be manually specified by using the option
+.BR --manpath .
+An empty argument disables the
+.I \%man\~page
+searching.
+.
+.Topic
+When no
+.I man\~path
+was set the
+.BR \%manpath (1)
+program is tried to determine one.
+.
+.Topic
+If this does not work a reasonable default path from
+.Env_var $PATH
+is determined.
+.
+.
+.P
+We now have a starting set of directories.
+.
+The first way to change this set is by adding names of
+.I operating
+.IR systems .
+.
+This assumes that
+.I \%man\~pages
+for several
+.I operating systems
+are installed.
+.
+This is not always true.
+.
+The names of such
+.I operating systems
+can be provided by 3 methods.
+.
+.Topic
+The environment variable
+.Env_var \%$SYSTEM
+has the lowest precedence.
+.
+.Topic
+This can be overridden by an option in
+.Env_var \%$MANOPT .
+.
+.Topic
+This again is overridden by the command line option
+.BR --systems .
+.
+.
+.P
+Several names of
+.I operating systems
+can be given by appending their names, separated by a comma.
+.
+.
+.P
+The
+.I man\~path
+is changed by appending each
+.I system
+name as subdirectory at the end of each directory of the set.
+.
+No directory of the
+.I man\~path
+set is kept.
+.
+But if no
+.I system
+name is specified the
+.I man\~path
+is left unchanged.
+.
+.
+.P
+After this, the actual set of directories can be changed by
+.I language
+information.
+.
+This assumes that there exist
+.I man\~pages
+in different languages.
+.
+The wanted
+.I language
+can be chosen by several methods.
+.
+.Topic
+Environment variable
+.Env_var $LANG .
+.
+.Topic
+This is overridden by
+.Env_var \%$LC_MESSAGES .
+.
+.Topic
+This is overridden by
+.Env_var $LC_ALL .
+.
+.Topic
+This can be overridden by providing an option in
+.Env_var \%$MANOPT .
+.
+.Topic
+All these environment variables are overridden by the command line
+option
+.BR --locale .
+.
+.
+.P
+The
+.I default language
+can be specified by specifying one of the pseudo-language parameters
+\f[CR]C\fP or \f[CR]\%POSIX\fP.
+.
+This is like deleting a formerly given
+.I language
+information.
+.
+The
+.I \%man\~pages
+in the
+.I default language
+are usually in English.
+.
+.
+.P
+Of course, the
+.I language
+name is determined by
+.BR man .
+In \f[CR]GNU\fP
+.BR man ,
+it is specified in the \%\f[CR]POSIX\~1003.1\fP based format:
+.P
+.nh
+\f[I]<language>\f[][\f[CB]_\f[]\f[I]<territory>\f[][\f[CB].\fP\
+\f[I]<character-set>\f[][\f[CB],\fP\f[I]<version>\fP]]],
+.hy
+.P
+but the two-letter code in
+.nh
+.I <language>
+.hy
+is sufficient for most purposes.
+.
+If for a complicated
+.I language
+formulation no
+.I \%man\~pages
+are found
+.B \%groffer
+searches the country part consisting of these first two characters as
+well.
+.
+.
+.P
+The actual directory set is copied thrice.
+.
+The
+.I language
+name is appended as subdirectory to each directory in the first copy
+of the actual directory set (this is only done when a language
+information is given).
+.
+Then the 2-letter abbreviation of the
+.I language
+name is appended as subdirectories to the second copy of the directory
+set (this is only done when the given language name has more than 2
+letters).
+.
+The third copy of the directory set is kept unchanged (if no
+.I language
+information is given this is the kept directory set).
+.
+These maximally 3 copies are appended to get the new directory set.
+.
+.
+.P
+We now have a complete set of directories to work with.
+.
+In each of these directories, the
+.I man
+files are separated in
+.IR sections .
+.
+The name of a
+.I section
+is represented by a single character, a digit between
+.I 1
+and
+.IR 9 ,
+or the character
+.I o
+or
+.IR n ,
+in this order.
+.
+.
+.P
+For each available
+.IR section ,
+a subdirectory
+.File_name man \fI<section>\fP
+exists containing all
+.I man
+files for this
+.IR section ,
+where
+.I <section>
+is a single character as described before.
+.
+Each
+.I man
+file in a
+.I section
+directory has the form
+.IR \%\f[CB]man\fP<section>\f[CB]/\fP<name>\f[CB].\fP<section>\
+[<extension>][\f[CB].\fP<compression>] ,
+where
+.I \%<extension>
+and
+.I \%<compression>
+are optional.
+.
+.I \%<name>
+is the name of the
+.I \%man\~page
+that is also specified as filespec argument on the command line.
+.
+.
+.P
+The
+.I extension
+is an addition to the section.
+.
+This postfix acts like a subsection.
+.
+An
+.I extension
+occurs only in the file name, not in name of the
+.I section
+subdirectory.
+.
+It can be specified on the command line.
+.
+.
+.P
+On the other hand, the
+.I compression
+is just an information on how the file is compressed.
+.
+This is not important for the user, such that it cannot be specified
+on the command line.
+.
+.
+.P
+There are 4 methods to specify a
+.I section
+on the command line:
+.
+.Topic
+Environment variable
+.Env_var \%$MANSECT
+.
+.Topic
+Command line option
+.B --sections
+.
+.Topic
+Appendix to the
+.I name
+argument in the form
+.I <name>.<section>
+.
+.Topic
+Preargument before the
+.I name
+argument in the form
+.I <section> <name>
+.
+.
+.P
+It is also possible to specify several
+.I sections
+by appending the single characters separated by colons.
+.
+One can imagine that this means to restrict the
+.I \%man\~page
+search to only some
+.IR sections .
+.
+The multiple
+.I sections
+are only possible for
+.Env_var \%$MANSECT
+and
+.BR --sections .
+.
+.
+.P
+If no
+.I section
+is specified all
+.I sections
+are searched one after the other in the given order, starting with
+.IR section\~1 ,
+until a suitable file is found.
+.
+.
+.P
+There are 4 methods to specify an
+.I extension
+on the command line.
+.
+But it is not necessary to provide the whole extension name, some
+abbreviation is good enough in most cases.
+.
+.Topic
+Environment variable
+.Env_var \%$EXTENSION
+.
+.Topic
+Command line option
+.B --extension
+.
+.Topic
+Appendix to the
+.I <name>.<section>
+argument in the form
+.I <name>.<section><extension>
+.
+.Topic
+Preargument before the
+.I name
+argument in the form
+.I <section><extension> <name>
+.
+.
+.P
+For further details on
+.I \%man\~page
+searching, see
+.BR \%man (1).
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Examples of man files"
+.\" --------------------------------------------------------------------
+.
+.TP
+.File_name /usr/share/man/man1/groff.1
+This is an uncompressed file for the
+.I \%man\~page
+\f[CR]groff\fP in
+.IR section\~1 .
+.
+It can be called by
+.EX
+\fIsh#\fR groffer\~groff
+.EE
+No
+.I section
+is specified here, so all
+.I sections
+should be searched, but as
+.I section\~1
+is searched first this file will be found first.
+.
+The file name is composed of the following components.
+.File_name /usr/share/man
+must be part of the
+.IR \%man\~path ;
+the subdirectory
+.File_name man1/
+and the part
+.File_name .1
+stand for the
+.IR section ;
+.File_name groff
+is the name of the
+.IR \%man\~page .
+.
+.
+.TP
+.File_name /usr/local/share/man/man7/groff.7.gz
+The file name is composed of the following components.
+.File_name /usr/local/share/man
+must be part of the
+.IR \%man\~path ;
+the subdirectory
+.File_name man7/
+and the part
+.File_name .7
+stand for the
+.IR section ;
+.File_name groff
+is the name of the
+.IR \%man\~page ;
+the final part
+.File_name .gz
+stands for a compression with
+.BR gzip (1).
+As the
+.I section
+is not the first one it must be specified as well.
+.
+This can be done by one of the following commands.
+.EX
+\fIsh#\fR\~groffer\~groff.7
+\fIsh#\fR\~groffer\~7\~groff
+\fIsh#\fR\~groffer\~\-\-sections=7\~groff
+.EE
+.
+.TP
+.File_name /usr/local/man/man1/ctags.1emacs21.bz2
+Here
+.File_name /usr/local/man
+must be in
+.IR \%man\~path ;
+the subdirectory
+.File_name man1/
+and the file name part
+.File_name .1
+stand for
+.IR section\~1 ;
+the name of the
+.I \%man\~page
+is
+.File_name ctags ;
+the section has an extension
+.File_name emacs21 ;
+and the file is compressed as
+.File_name .bz2
+with
+.BR bzip2 (1).
+The file can be viewed with one of the following commands
+.EX
+\fIsh#\fR\~groffer\~ctags.1e
+\fIsh#\fR\~groffer\~1e\~ctags
+\fIsh#\fR\~groffer\~\-\-extension=e\~\-\-sections=1\~ctags
+.EE
+where \f[CR]e\fP works as an abbreviation for the extension
+\f[CR]emacs21\fP.
+.
+.
+.TP
+.File_name /usr/man/linux/de/man7/man.7.Z
+The directory
+.File_name /usr/man
+is now part of the
+.IR \%man\~path ;
+then there is a subdirectory for an
+.I operating system
+name
+.File_name linux/ ;
+next comes a subdirectory
+.File_name de/
+for the German
+.IR language ;
+the
+.I section
+names
+.File_name man7
+and
+.File_name .7
+are known so far;
+.File_name man
+is the name of the
+.IR \%man\~page ;
+and
+.File_name .Z
+signifies the compression that can be handled by
+.BR gzip (1).
+We want now show how to provide several values for some options.
+.
+That is possible for
+.I sections
+and
+.I operating system
+names.
+.
+So we use as
+.I sections\~5
+and
+.I 7
+and as
+.I system
+names
+.I linux
+and
+.IR aix .
+The command is then
+.sp
+.EX
+\fIsh#\fR groffer\~\-\-locale=de\~\-\-sections=5:7\~\-\-systems=linux,aix\~man
+\fIsh#\fR LANG=de\~MANSECT=5:7\~SYSTEM=linux,aix\~groffer\~man
+.EE
+.
+.
+.\" --------------------------------------------------------------------
+.SH DECOMPRESSION
+.\" --------------------------------------------------------------------
+.
+The program has a decompression facility.
+.
+If standard input or a file that was retrieved from the command line
+parameters is compressed with a format that is supported by either
+.BR \%gzip (1)
+or
+.BR \%bzip2 (1)
+it is decompressed on-the-fly.
+.
+This includes the \f[CR]GNU\fP
+.BR \%.gz ,
+.BR \%.bz2 ,
+and the traditional
+.B \%.Z
+compression.
+.
+The program displays the concatenation of all decompressed input in
+the sequence that was specified on the command line.
+.
+.
+.\" --------------------------------------------------------------------
+.SH "ENVIRONMENT"
+.\" --------------------------------------------------------------------
+.
+The
+.B \%groffer
+program supports many system variables, most of them by courtesy of
+other programs.
+.
+All environment variables of
+.BR \%groff (@MAN1EXT@)
+and \f[CR]GNU\fP
+.BR \%man (1)
+and some standard system variables are honored.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Native groffer Variables"
+.\" --------------------------------------------------------------------
+.
+.TP
+.Env_var \%$GROFFER_OPT
+Store options for a run of
+.BR \%groffer .
+.
+The options specified in this variable are overridden by the options
+given on the command line.
+.
+The content of this variable is run through the shell builtin `eval';
+so arguments containing white-space or special shell characters should
+be quoted.
+.
+Do not forget to export this variable, otherwise it does not exist
+during the run of
+.BR groffer .
+.
+.
+.\" --------------------------------------------------------------------
+.SS "System Variables"
+.\" --------------------------------------------------------------------
+.
+The following variables have a special meaning for
+.BR \%groffer .
+.
+.
+.TP
+.Env_var \%$DISPLAY
+If this variable is set this indicates that the \%\f[CR]X\~Window\fP
+system is running.
+.
+Testing this variable decides on whether graphical or text output is
+generated.
+.
+This variable should not be changed by the user carelessly, but it can
+be used to start the graphical
+.B \%groffer
+on a remote \%\f[CR]X\~Window\fP terminal.
+.
+For example, depending on your system,
+.B \%groffer
+can be started on the second monitor by the command
+.sp
+.EX
+\fIsh#\fR DISPLAY=:0.1\~groffer\~what.ever &
+.EE
+.
+.
+.TP
+.Env_var \%$LC_ALL
+.TQ
+.Env_var \%$LC_MESSAGES
+.TQ
+.Env_var $LANG
+If one of these variables is set (in the above sequence), its content
+is interpreted as the locale, the language to be used, especially when
+retrieving
+.IR \%man\~pages .
+.
+A locale name is typically of the form
+.nh
+.IR language [\c
+.B _\c
+.IR territory [\c
+.B .\c
+.IR codeset [\c
+.B @\c
+.IR modifier ]]],
+.hy
+where
+.I \%language
+is an ISO 639 language code,
+.I \%territory
+is an ISO 3166 country code, and
+.I \%codeset
+is a character set or encoding identifier like ISO-8859-1 or UTF-8;
+see
+.BR \%setlocale (3).
+.
+The locale values \f[CR]C\fP and \%\f[CR]POSIX\fP
+stand for the default, i.e. the
+.I \%man\~page
+directories without a language prefix.
+.
+This is the same behavior as when all 3\~variables are unset.
+.
+.
+.TP
+.Env_var \%$PAGER
+This variable can be used to set the pager for the tty output.
+.
+For example, to disable the use of a pager completely set this
+variable to the
+.BR \%cat (1)
+program
+.sp
+.EX
+\fIsh#\fR PAGER=cat\~groffer\~anything
+.EE
+.sp
+.
+.TP
+.Env_var $PATH
+All programs within the
+.B \%groffer
+script are called without a fixed path.
+.
+Thus this environment variable determines the set of programs used
+within the run of
+.BR \%groffer .
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Groff Variables"
+.\" --------------------------------------------------------------------
+.
+The
+.B \%groffer
+program internally calls
+.BR \%groff ,
+so all environment variables documented in
+.BR \%groff (@MAN1EXT@)
+are internally used within
+.B \%groffer
+as well.
+.
+The following variable has a direct meaning for the
+.B \%groffer
+program.
+.
+.TP
+.Env_var \%$GROFF_TMPDIR
+If the value of this variable is an existing, writable directory,
+.B \%groffer
+uses it for storing its temporary files, just as
+.B groff
+does.
+.
+See the
+.BR \%groff (@MAN1EXT@)
+man page for more details on the location of temporary files.
+.
+.
+.\" --------------------------------------------------------------------
+.SS "Man Variables"
+.\" --------------------------------------------------------------------
+.
+Parts of the functionality of the
+.B man
+program were implemented in
+.BR \%groffer ;
+support for all environment variables documented in
+.BR \%man (1)
+was added to
+.BR \%groffer ,
+but the meaning was slightly modified due to the different approach in
+.BR \%groffer ;
+but the user interface is the same.
+.
+The
+.B man
+environment variables can be overwritten by options provided with
+.Env_var \%$MANOPT ,
+which in turn is overwritten by the command line.
+.
+.
+.TP
+.Env_var \%$EXTENSION
+Restrict the search for
+.I \%man\~pages
+to files having this extension.
+.
+This is overridden by option
+.BR --extension ;
+see there for details.
+.
+.
+.TP
+.Env_var \%$MANOPT
+This variable contains options as a preset for
+.BR \%man (1).
+As not all of these are relevant for
+.B \%groffer
+only the essential parts of its value are extracted.
+.
+The options specified in this variable overwrite the values of the
+other environment variables that are specific to
+.IR man .
+.
+All options specified in this variable are overridden by the options
+given on the command line.
+.
+.
+.TP
+.Env_var \%$MANPATH
+If set, this variable contains the directories in which the
+.I \%man\~page
+trees are stored.
+.
+This is overridden by option
+.BR \%--manpath .
+.
+.
+.TP
+.Env_var \%$MANSECT
+If this is a colon separated list of section names, the search for
+.I \%man\~pages
+is restricted to those manual sections in that order.
+.
+This is overridden by option
+.BR --sections .
+.
+.
+.TP
+.Env_var \%$SYSTEM
+If this is set to a comma separated list of names these are interpreted
+as
+.I \%man\~page
+trees for different operating systems.
+.
+This variable can be overwritten by option
+.BR --systems ;
+see there for details.
+.
+.
+.P
+The environment variable
+.Env_var \%$MANROFFSEQ
+is ignored by
+.B \%groffer
+because the necessary preprocessors are determined automatically.
+.
+.
+.\" --------------------------------------------------------------------
+.SH "CONFIGURATION FILES"
+.\" --------------------------------------------------------------------
+.
+The
+.B \%groffer
+program can be preconfigured by two configuration files.
+.
+.
+.TP
+.File_name \%/etc/groff/groffer.conf
+System-wide configuration file for
+.BR \%groffer .
+.
+.
+.TP
+.File_name \%$HOME/.groff/groffer.conf
+User-specific configuration file for
+.BR \%groffer ,
+where
+.Env_var \%$HOME
+denotes the user's home directory.
+.
+This file is called after the system-wide configuration file to enable
+overriding by the user.
+.
+.
+.P
+Both files are handled for the configuration, but the configuration
+file in
+.File_name /etc
+comes first; it is overwritten by the configuration file in the home
+directory; both configuration files are overwritten by the environment
+variable
+.Env_var \%$GROFFER_OPT ;
+everything is overwritten by the command line arguments.
+.
+.
+.P
+The configuration files contain options that should be called as
+default for every
+.B \%groffer
+run.
+.
+These options are written in lines such that each contains either a
+long option, a short option, or a short option cluster; each with or
+without an argument.
+.
+So each line with configuration information starts with a minus
+character
+.RB ` \- ';
+a line with a long option starts with two minus characters
+.RB ` \-\- ',
+a line with a short option or short option cluster starts with a
+single minus
+.RB ` \- '.
+.
+.
+.P
+The option names in the configuration files may not be abbreviated,
+they must be exact.
+.
+.
+.P
+The argument for a long option can be separated from the option name
+either by an equal sign
+.RB ` = '
+or by whitespace, i.e. one or several space or tab characters.
+.
+An argument for a short option or short option cluster can be directly
+appended to the option name or separated by whitespace.
+.
+The end of an argument is the end of the line.
+.
+It is not allowed to use a shell environment variable in an option
+name or argument.
+.
+.
+.P
+It is not necessary to use quotes in an option or argument, except for
+empty arguments.
+.
+An empty argument can be provided by appending a pair of quotes to the
+separating equal sign or whitespace; with a short option, the
+separator can be omitted as well.
+.
+For a long option with a separating equal sign
+.RB ` = ',
+the pair of quotes can be omitted, thus ending the line with the
+separating equal sign.
+.
+All other quote characters are cancelled internally.
+.
+.
+.P
+In the configuration files, arbitrary whitespace is allowed at the
+beginning of each line, it is just ignored.
+.
+Each whitespace within a line is replaced by a single space character
+` ' internally.
+.
+.
+.P
+All lines of the configuration lines that do not start
+with a minus character are ignored, such that comments starting with
+.RB ` # '
+are possible.
+.
+So there are no shell commands in the configuration files.
+.
+.
+.P
+As an example, consider the following configuration file that can be
+used either in
+.File_name \%/etc/groff/groffer.conf
+or
+.File_name \%~/.groff/groffer.conf .
+.
+.
+.P
+.ft CR
+.nh
+.nf
+# groffer configuration file
+#
+# groffer options that are used in each call of groffer
+\-\-foreground=DarkBlue
+\-\-resolution=100
+\-\-x\-viewer=gxditview \-geometry 900x1200
+\-\-pdf\-viewer xpdf \-Z 150
+.fi
+.hy
+.ft
+.
+.
+.P
+The lines starting with
+.B #
+are just ignored, so they act as command lines.
+.
+This configuration sets four
+.B \%groffer
+options (the lines starting with
+.RB ` \- ').
+This has the following effects:
+.
+.
+.Topic
+Use a text color of
+.B \%DarkBlue
+in all viewers that support this, such as
+.BR \%gxditview .
+.
+.
+.Topic
+Use a resolution of
+.B 100dpi
+in all viewers that support this, such as
+.BR \%gxditview .
+.
+By this, the default device in
+.I x mode
+is set to
+.BR X100 .
+.
+.
+.Topic
+Force
+.BR \%gxditview (@MAN1EXT@)
+as the
+.I \%x-mode
+viewer using the geometry option for setting the width to
+.B 900px
+and the height to
+.BR 1200px .
+This geometry is suitable for a resolution of
+.BR 100dpi .
+.
+.
+.Topic
+Use
+.BR \%xpdf (1)
+as the
+.I \%pdf-mode
+viewer with the argument
+.B \-Z
+.BR 150 .
+.
+.
+.\" --------------------------------------------------------------------
+.SH "EXAMPLES"
+.\" --------------------------------------------------------------------
+.
+The usage of
+.B \%groffer
+is very easy.
+.
+Usually, it is just called with a file name or
+.IR \%man\~page .
+.
+The following examples, however, show that
+.B \%groffer
+has much more fancy capabilities.
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~/usr/local/share/doc/groff/meintro.ms.gz
+.EE
+.sp
+Decompress, format and display the compressed file
+.File_name meintro.ms.gz
+in the directory
+.File_name /usr/local/share/doc/groff ,
+using the standard viewer
+.B \%gxditview
+as graphical viewer when in \%\f[CR]X\~Window\fP, or the
+.BR \%less (1)
+pager program when not in \%\f[CR]X\~Window\fP.
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~groff
+.EE
+.sp
+If the file
+.File_name \%./groff
+exists use it as input.
+.
+Otherwise interpret the argument as a search for the
+.I \%man\~page
+named
+.B \%groff
+in the smallest possible
+.IR \%man\~section ,
+being section 1 in this case.
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~man:groff
+.EE
+.sp
+search for the
+.I \%man\~page
+of
+.B \%groff
+even when the file
+.File_name ./groff
+exists.
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~groff.7
+\fIsh#\fR\~groffer\~7\~groff
+.EE
+.sp
+search the
+.I \%man\~page
+of
+.B \%groff
+in
+.I \%man\~section
+.BR 7 .
+This section search works only for a digit or a single character from
+a small set.
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~fb.modes
+.EE
+.sp
+If the file
+.File_name ./fb.modes
+does not exist interpret this as a search for the
+.I \%man\~page
+of
+.BR fb.modes .
+As the extension
+.I \%modes
+is not a single character in classical section style the argument is
+not split to a search for
+.BR fb .
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~groff\~\[cq]troff(1)\[cq]\~man:roff
+.EE
+.sp
+The arguments that are not existing files are looked-up as the
+following
+.IR \%man\~pages :
+.B \%groff
+(automatic search, should be found in \fIman\fP\~section\~1),
+.B \%troff
+(in section\~1),
+and
+.B \%roff
+(in the section with the lowest number, being\~7 in this case).
+.
+The quotes around
+.nh
+.I \[cq]troff(1)\[cq]
+.hy
+are necessary because the parentheses are special shell characters;
+escaping them with a backslash character
+.I \[rs](
+and
+.I \[rs])
+would be possible, too.
+.
+The formatted files are concatenated and displayed in one piece.
+.
+.sp
+.EX
+\fIsh#\fR\~LANG=de\~groffer\~--man\~--www\~--www-viewer=galeon\~ls
+.EE
+.sp
+Retrieve the German
+.I \%man\~page
+(language
+.IR de )
+for the
+.B ls
+program, decompress it, format it to
+.I \%html
+format
+.nh
+.RI ( \%www\~mode )
+.hy
+and view the result in the web browser
+.BR \%galeon .
+The option
+.B --man
+guarantees that the
+.I \%man\~page
+is retrieved, even when a local file
+.File_name \%ls
+exists in the actual directory.
+.
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~--source\~'man:roff(7)'
+.EE
+.sp
+Get the
+.I \%man\~page
+called
+.I \%roff
+in \fIman\fP\~section 7, decompress it, and print its unformatted
+content, its source code.
+.
+.
+.sp
+.EX
+\fIsh#\fR\~groffer\~--de-p\~--in\~--ap
+.EE
+.sp
+This is a set of abbreviated arguments, it is determined as
+.br
+.sp
+.EX
+\fIsh#\fR\~groffer\~--debug-params\~--intermediate-output\~--apropos
+.EE
+.sp
+.
+.sp
+.EX
+\fIsh#\fR\~cat\~file.gz\~|\~groffer\~-Z\~-mfoo
+.EE
+.sp
+.
+The file
+.File_name file.gz
+is sent to standard input, this is decompressed, and then this is
+transported to the
+.I \%groff intermediate output mode
+without post-processing
+.RB ( groff
+option
+.BR -Z ),
+using macro package
+.I \%foo
+.RB ( groff
+option
+.BR -m ).
+.
+.
+.sp
+.EX
+\fIsh#\fR\~echo\~'\[rs]f[CB]WOW!'\~|
+> groffer --x --bg red --fg yellow --geometry 200x100 -
+.EX
+.sp
+.
+Display the word \f[CB]WOW!\fP in a small window in constant-width
+bold font, using color yellow on red background.
+.
+.
+.\" --------------------------------------------------------------------
+.SH "COMPATIBILITY"
+.\" --------------------------------------------------------------------
+.
+The
+.B \%groffer
+program is written in Perl, the Perl version during writing was v5.8.8.
+.
+.
+.P
+.B \%groffer
+provides its own parser for command line arguments that is compatible
+to both \%\f[CR]POSIX\fP
+.BR \%getopts (1)
+and \%\f[CR]GNU\fP
+.BR \%getopt (1).
+It can handle option arguments and file names containing white space
+and a large set of special characters.
+.
+The following standard types of options are supported.
+.
+.
+.Topic
+The option consisting of a single minus
+.B -
+refers to standard input.
+.
+.
+.Topic
+A single minus followed by characters refers to a single character
+option or a combination thereof; for example, the
+.B \%groffer
+short option combination
+.B -Qmfoo
+is equivalent to
+.BR -Q\~\-m\~foo .
+.
+.
+.Topic
+Long options are options with names longer than one character; they
+are always preceded by a double minus.
+.
+An option argument can either go to the next command line argument or
+be appended with an equal sign to the argument; for example,
+.B --long=arg
+is equivalent to
+.BR --long\~arg .
+.
+.
+.Topic
+An argument of
+.B --
+ends option parsing; all further command line arguments are
+interpreted as
+.I \%filespec
+parameters, i.e. file names or constructs for searching
+.IR \%man\~pages ).
+.
+.
+.Topic
+All command line arguments that are neither options nor option
+arguments are interpreted as
+.I \%filespec
+parameters and stored until option parsing has finished.
+.
+For example, the command line
+.sp
+.EX
+\fIsh#\fR\~groffer file1 -a -o arg file2
+.EE
+.sp
+is equivalent to
+.sp
+.EX
+\fIsh#\fR\~groffer -a -o arg -- file1 file2
+.EE
+.sp
+.
+.P
+The free mixing of options and
+.I \%filespec
+parameters follows the GNU principle.
+.
+That does not fulfill the strange option behavior of \%\f[CR]POSIX\fP
+that ends option processing as soon as the first non-option argument
+has been reached.
+.
+The end of option processing can be forced by the option
+.RB ` \-\- '
+anyway.
+.
+.
+.\" --------------------------------------------------------------------
+.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
+.B \%groffer
+you are using.
+.
+.
+.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"
+.\" --------------------------------------------------------------------
+.
+.P
+.BR \%groff (@MAN1EXT@),
+.BR \%@g@troff (@MAN1EXT@)
+.RS
+Details on the options and environment variables available in
+.BR \%groff ;
+all of them can be used with
+.BR \%groffer .
+.RE
+.
+.
+.TP
+.BR \%groff (@MAN7EXT@)
+Documentation of the
+.I \%groff
+language.
+.
+.
+.TP
+.BR \%grog (@MAN1EXT@)
+Internally,
+.B \%groffer
+tries to guess the
+.B \%groff
+command line options from the input using this program.
+.
+.
+.TP
+.BR groff_out (@MAN5EXT@)
+Documentation on the
+.I \%groff intermediate output
+.nh
+.RI ( ditroff
+output).
+.hy
+.
+.
+.TP
+.BR groff_tmac (@MAN5EXT@)
+Documentation on the
+.I \%groff
+macro files.
+.
+.
+.TP
+.BR \%man (1)
+The standard program to display
+.IR \%man\~pages .
+.
+The information there is only useful if it is the
+.I \%man\~page
+for GNU
+.BR man .
+Then it documents the options and environment variables that are
+supported by
+.BR \%groffer .
+.
+.
+.P
+.BR \%gxditview (@MAN1EXT@),
+.BR \%xditview (1x)
+.RS
+Viewers for
+.BR \%groffer 's
+.IR \%x\~mode .
+.RE
+.
+.
+.P
+.BR \%kpdf (1),
+.BR \%kghostview (1),
+.BR \%evince (1),
+.BR \%ggv (1),
+.BR \%gv (1),
+.BR \%ghostview (1),
+.BR \%gs (1)
+.RS
+Viewers for
+.BR \%groffer 's
+.IR \%ps\~mode .
+.RE
+.
+.
+.P
+.BR \%kpdf (1),
+.BR \%acroread (1),
+.BR \%evince (1),
+.BR \%xpdf (1),
+.BR \%gpdf (1),
+.BR \%kghostview (1),
+.BR \%ggv (1)
+.RS
+Viewers for
+.BR \%groffer 's
+.IR \%pdf\~mode .
+.RE
+.
+.
+.P
+.BR \%kdvi (1),
+.BR \%xdvi (1),
+.BR \%dvilx (1)
+.RS
+Viewers for
+.BR \%groffer 's
+.IR \%dvi\~mode .
+.RE
+.
+.
+.P
+.BR \%konqueror (1),
+.BR \%epiphany (1),
+.BR \%firefox (1),
+.BR \%mozilla (1),
+.BR \%netscape (1),
+.BR \%lynx (1)
+.RS
+Web-browsers for
+.BR \%groffer 's
+.I \%html
+or
+.IR \%www\~mode .
+.RE
+.
+.
+.TP
+.BR \%less (1)
+Standard pager program for the
+.IR \%tty\~mode .
+.
+.
+.P
+.BR \%gzip (1),
+.BR \%bzip2 (1)
+.RS
+The decompression programs supported by
+.BR \%groffer .
+.RE
+.
+.
+.\" --------------------------------------------------------------------
+.SH "AUTHOR"
+.\" --------------------------------------------------------------------
+.author
+.
+.
+.\" --------------------------------------------------------------------
+.SH "COPYING"
+.\" --------------------------------------------------------------------
+.copyleft
+.
+.
+.\" --------------------------------------------------------------------
+.\" Emacs settings
+.\" --------------------------------------------------------------------
+.
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/contrib/groffer/perl/groffer.pl b/contrib/groffer/perl/groffer.pl
new file mode 100755
index 00000000..766bc2e6
--- /dev/null
+++ b/contrib/groffer/perl/groffer.pl
@@ -0,0 +1,2209 @@
+#! /usr/bin/env perl
+
+# groffer - display groff files
+
+# Source file position: <groff-source>/contrib/groffer/perl/groffer.pl
+# Installed position: <prefix>/bin/groffer
+
+# Copyright (C) 2006, 2009, 2011, 2013
+# Free Software Foundation, Inc.
+
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 29 Mar 2013
+
+# 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/>.
+
+########################################################################
+
+use strict;
+use warnings;
+#use diagnostics;
+
+# temporary dir and files
+use File::Temp qw/ tempfile tempdir /;
+
+# needed for temporary dir
+use File::Spec;
+
+# for `copy' and `move'
+use File::Copy;
+
+# for fileparse, dirname and basename
+use File::Basename;
+
+# current working directory
+use Cwd;
+
+# $Bin is the directory where this script is located
+use FindBin;
+
+
+########################################################################
+# system variables and exported variables
+########################################################################
+
+our $Dev_Null;
+our $Umask;
+our @Path;
+our $Start_Dir;
+
+our $tmpdir = '';
+our ($fh_cat, $tmp_cat);
+our ($fh_stdin, $tmp_stdin);
+
+our @Addopts_Groff;
+our %Debug;
+our %Opt;
+
+our $Has_Compression;
+our $Has_bzip;
+
+our $Output_File_Name;
+
+our $Apropos_Prog;
+our $Filespec_Arg;
+our $Filespec_Is_Man;
+our $Macro_Pkg;
+our $Manspec;
+our $No_Filespecs;
+our $Special_Filespec;
+our $Special_Setup;
+
+our %Man;
+
+BEGIN {
+ $Dev_Null = File::Spec->devnull();
+
+ $Umask = umask 077;
+
+ $Start_Dir = getcwd;
+
+ # flush after each print or write command
+ $| = 1;
+}
+
+
+########################################################################
+# read-only variables with double-@ construct
+########################################################################
+
+our $File_split_env_sh;
+our $File_version_sh;
+our $Groff_Version;
+
+BEGIN {
+ {
+ my $before_make; # script before run of `make'
+ {
+ my $at = '@';
+ $before_make = 1 if '@VERSION@' eq "${at}VERSION${at}";
+ }
+
+ my %at_at;
+ my $file_perl_test_pl;
+ my $groffer_libdir;
+
+ if ($before_make) {
+ my $groffer_perl_dir = $FindBin::Bin;
+ my $groffer_top_dir = File::Spec->catdir($groffer_perl_dir, '..');
+ $groffer_top_dir = Cwd::realpath($groffer_top_dir);
+ $at_at{'BINDIR'} = $groffer_perl_dir;
+ $at_at{'G'} = '';
+ $at_at{'LIBDIR'} = '';
+ $groffer_libdir = $groffer_perl_dir;
+ $file_perl_test_pl = File::Spec->catfile($groffer_perl_dir,
+ 'perl_test.pl');
+ $File_version_sh = File::Spec->catfile($groffer_top_dir, 'version.sh');
+ $Groff_Version = '';
+ } else {
+ $Groff_Version = '@VERSION@';
+ $at_at{'BINDIR'} = '@BINDIR@';
+ $at_at{'G'} = '@g@';
+ $at_at{'LIBDIR'} = '@libdir@';
+ $groffer_libdir = '@groffer_dir@';
+ $file_perl_test_pl = File::Spec->catfile($groffer_libdir,
+ 'perl_test.pl');
+ $File_version_sh = File::Spec->catfile($groffer_libdir, 'version.sh');
+ }
+
+ die "$groffer_libdir is not an existing directory;"
+ unless -d $groffer_libdir;
+
+ unshift(@INC, $groffer_libdir);
+
+ $File_split_env_sh = File::Spec->catfile($groffer_libdir, 'split_env.sh');
+ die "$File_split_env_sh does not exist;" unless -f "$File_split_env_sh";
+
+ # test perl on suitable version
+ die "$file_perl_test_pl does not exist;" unless -f "$file_perl_test_pl";
+ do "$file_perl_test_pl" or die "Perl test: $@";
+
+ require 'func.pl';
+ require 'man.pl';
+
+ @Path = &path_uniq( File::Spec->path() );
+
+ if ( &where_is_prog('gzip') ) {
+ $Has_Compression = 1;
+ $Has_bzip = 1 if &where_is_prog('bzip2');
+ }
+ }
+}
+
+
+########################################################################
+# modes, viewers, man sections, and defaults
+########################################################################
+
+# configuration files
+my @Conf_Files = (File::Spec->catfile(File::Spec->rootdir(),
+ 'etc', 'groff', 'groffer.conf'),
+ File::Spec->catfile("$ENV{'HOME'}", '.groff',
+ 'groffer.conf')
+ );
+
+my @Default_Modes = ('pdf', 'html', 'ps', 'x', 'dvi', 'tty');
+my $Default_Resolution = 75;
+my $Default_tty_Device = 'latin1';
+
+my @Macro_Packages = ('-man', '-mdoc', '-me', '-mm', '-mom', '-ms');
+
+my %Viewer_tty = ('DVI' => [],
+ 'HTML' => ['lynx', 'w3m'],
+ 'PDF' => [],
+ 'PS' => [],
+ 'TTY' => ['less -r -R', 'more', 'pager'],
+ 'X' => [],
+ );
+
+my %Viewer_X = ('DVI' => ['kdvi', 'xdvi', 'dvilx'],
+ 'HTML' => ['konqueror', 'epiphany'. 'mozilla-firefox',
+ 'firefox', 'mozilla', 'netscape', 'galeon',
+ 'opera', 'amaya','arena', 'mosaic'],
+ 'PDF' => ['okular', 'kpdf', 'acroread', 'evince',
+ 'xpdf -z 150', 'gpdf', 'xpdf', 'zathura'.
+ 'epdfview', 'qpdfview', 'apvlv', 'qpdfview',
+ 'kghostview --scale 1.45', 'gv', 'ggv'],
+ 'PS' => ['gs', 'gs_x11', 'ghostscript', 'ghostview',
+ 'kghostview --scale 1.45',
+ 'gv', 'okular', 'kpdf', 'evince', 'ggv'],
+ 'TTY' => ['xless'],
+ 'X' => ['gxditview', 'xditview'],
+ );
+
+%Man = ('ALL' => 0,
+ 'AUTO_SEC' => ['1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'n', 'o'],
+ 'ENABLE' => 1,
+ 'EXT' => '',
+ 'FORCE' => 0,
+ 'IS_SETUP' => 0,
+ 'MANSPEC' => {},
+ 'LANG' => '',
+ 'LANG2' => '',
+ 'PATH' => [],
+ 'SEC' => [],
+ 'SEC_CHARS' => '',
+ 'SYS' => [],
+ );
+$Man{'AUTO_SEC_CHARS'} = join('', @{$Man{'AUTO_SEC'}});
+
+
+########################################################################
+# given options, main_set_options()
+########################################################################
+
+my %Opts_Cmdline_Short;
+my %Opts_Cmdline_Long;
+my $Opts_Cmdline_Long_Str;
+my %Opts_Cmdline_Double;
+my %Opts_Groff_Short;
+
+sub main_set_options {
+ # the following options are ignored in groffer.pl, but are kept from
+ # groffer.sh: --shell arg, --debug-shell
+
+ my @opts_ignored_short_na = ();
+ my @opts_ignored_short_arg = ();
+
+ my @opts_ignored_long_na = ('debug-shell');
+
+ my @opts_ignored_long_arg = ('shell');
+
+
+ ###### groffer native options
+
+ my @opts_groffer_short_na = ('h', 'Q', 'v', 'V', 'X', 'Z');
+ my @opts_groffer_short_arg = ('T');
+
+ my @opts_groffer_long_na = ('auto', 'apropos', 'apropos-data',
+ 'apropos-devel', 'apropos-progs', 'debug', 'debug-all',
+ 'debug-filenames', 'debug-func', 'debug-grog', 'debug-not-func',
+ 'debug-keep', 'debug-lm', 'debug-params', 'debug-stacks',
+ 'debug-tmpdir', 'debug-user', 'default', 'do-nothing', 'dvi',
+ 'groff', 'help', 'intermediate-output', 'html', 'man',
+ 'no-location', 'no-man', 'no-special', 'pdf', 'ps', 'rv', 'source',
+ 'text', 'to-stdout', 'text-device', 'tty', 'tty-device', 'version',
+ 'whatis', 'where', 'www', 'x', 'X');
+
+### main_set_options()
+ my @opts_groffer_long_arg = ('default-modes', 'device',
+ 'dvi-viewer', 'dvi-viewer-tty', 'extension', 'fg', 'fn', 'font',
+ 'foreground', 'html-viewer', 'html-viewer-tty', 'mode',
+ 'pdf-viewer', 'pdf-viewer-tty', 'print', 'ps-viewer',
+ 'ps-viewer-tty', 'title', 'tty-viewer', 'tty-viewer-tty',
+ 'www-viewer', 'www-viewer-tty', 'x-viewer', 'x-viewer-tty',
+ 'X-viewer', 'X-viewer-tty');
+
+ ##### groffer options inhereted from groff
+
+ my @opts_groff_short_na = ('a', 'b', 'c', 'C', 'e', 'E', 'g', 'G',
+ 'i', 'k', 'l', 'N', 'p', 'R', 's', 'S', 't', 'U', 'z');
+
+ my @opts_groff_short_arg = ('d', 'f', 'F', 'I', 'K', 'L', 'm', 'M', 'n',
+ 'o', 'P', 'r', 'w', 'W');
+
+ my @opts_groff_long_na = ();
+ my @opts_groff_long_arg = ();
+
+ ##### groffer options inhereted from the X Window toolkit
+
+ my @opts_x_short_na = ();
+ my @opts_x_short_arg = ();
+
+ my @opts_x_long_na = ('iconic', 'rv');
+
+ my @opts_x_long_arg = ('background', 'bd', 'bg', 'bordercolor',
+ 'borderwidth', 'bw', 'display', 'fg', 'fn', 'font', 'foreground',
+ 'ft', 'geometry', 'resolution', 'title', 'xrm');
+
+### main_set_options()
+ ###### groffer options inherited from man
+
+ my @opts_man_short_na = ();
+ my @opts_man_short_arg = ();
+
+ my @opts_man_long_na = ('all', 'ascii', 'catman', 'ditroff',
+ 'local-file', 'location', 'troff', 'update');
+
+ my @opts_man_long_arg = ('locale', 'manpath', 'pager',
+ 'preprocessor', 'prompt', 'sections', 'systems', 'troff-device');
+
+ ###### additional options for parsing evironment variable $MANOPT only
+
+ my @opts_manopt_short_na = ('7', 'a', 'c', 'd', 'D', 'f', 'h', 'k',
+ 'l', 't', 'u', 'V', 'w', 'Z');
+
+ my @opts_manopt_short_arg = ('e', 'L', 'm', 'M', 'p', 'P', 'r', 'S',
+ 'T');
+
+ my @opts_manopt_long_na = (@opts_man_long_na, 'apropos', 'debug',
+ 'default', 'help', 'html', 'ignore-case', 'location-cat',
+ 'match-case', 'troff', 'update', 'version', 'whatis', 'where',
+ 'where-cat');
+
+ my @opts_manopt_long_arg = (@opts_man_long_na, 'config_file',
+ 'encoding', 'extension', 'locale');
+
+### main_set_options()
+ ###### collections of command line options
+
+ # There are two hashes that control the whole of the command line
+ # options, one for short and one for long options. Options without
+ # and with arguments are mixed by advicing a value of 0 for an option
+ # without argument and a value of 1 for an option with argument.
+ # The options are with leading minus.
+
+ foreach (@opts_groffer_short_na, @opts_groff_short_na,
+ @opts_x_short_na, @opts_man_short_na, @opts_ignored_short_na) {
+ $Opts_Cmdline_Short{"-$_"} = 0 if $_;
+ }
+ foreach (@opts_groffer_short_arg, @opts_groff_short_arg,
+ @opts_x_short_arg, @opts_man_short_arg, @opts_ignored_short_arg) {
+ $Opts_Cmdline_Short{"-$_"} = 1 if $_;
+ }
+
+ foreach (@opts_groffer_long_na, @opts_groff_long_na,
+ @opts_x_long_na, @opts_man_long_na, @opts_ignored_long_na) {
+ $Opts_Cmdline_Long{"--$_"} = 0 if $_;
+ }
+ foreach (@opts_groffer_long_arg, @opts_groff_long_arg,
+ @opts_x_long_arg, @opts_man_long_arg, @opts_ignored_long_arg) {
+ $Opts_Cmdline_Long{"--$_"} = 1 if $_;
+ }
+
+ # For determining abbreviations of an option take two spaces as join
+ # for better check.
+ # The options are without leading minus.
+ $Opts_Cmdline_Long_Str = join ' ', keys %Opts_Cmdline_Long;
+ if ($Opts_Cmdline_Long_Str) {
+ $Opts_Cmdline_Long_Str = " $Opts_Cmdline_Long_Str ";
+ $Opts_Cmdline_Long_Str =~ s/--//g;
+ }
+
+### main_set_options()
+ # options with equal meaning are mapped to a single option name
+ # all of these have leading minus characters
+ %Opts_Cmdline_Double = ('-h' => '--help',
+ '-Q' => '--source',
+ '-T' => '--device',
+ '-v' => '--version',
+ '-Z' => '--intermediate-output',
+ '--bd' => '--bordercolor',
+ '--bg' => '--background',
+ '--bw' => '--borderwidth',
+ '--debug-all' => '--debug',
+ '--ditroff' => '--intermediate-output',
+ '--dvi-viewer-tty' => '--dvi-viewer',
+ '--fg' => '--foreground',
+ '--fn' => '--font',
+ '--ft' => '--font',
+ '--html-viewer-tty' => '--html-viewer',
+ '--pdf-viewer-tty' => '--pdf-viewer',
+ '--ps-viewer-tty' => '--ps-viewer',
+ '--troff-device' => '--device',
+ '--tty-device' => '--text-device',
+ '--tty-viewer' => '--pager',
+ '--tty-viewer-tty' => '--pager',
+ '--where' => '--location',
+ '--www' => '--html',
+ '--www-viewer' => '--html-viewer',
+ '--www-viewer-tty' => '--html-viewer',
+ '--x-viewer-tty' => '--x-viewer',
+ '--X' => '--x',
+ '--X-viewer' => '--x-viewer',
+ '--X-viewer-tty' => '--x-viewer',
+ );
+
+ # groff short options with leading minus
+ foreach (@opts_groff_short_na) {
+ $Opts_Groff_Short{"-$_"} = 0;
+ }
+ foreach (@opts_groff_short_arg) {
+ $Opts_Groff_Short{"-$_"} = 1;
+ }
+
+} # main_set_options()
+
+
+########################################################################
+# $MANOPT, main_parse_MANOPT()
+########################################################################
+
+# handle environment variable $MANOPT
+my @Manopt;
+
+sub main_parse_MANOPT {
+ if ($ENV{'MANOPT'}) {
+ @Manopt = `sh $File_split_env_sh MANOPT`;
+ chomp @Manopt;
+
+ my @manopt;
+ # %opts stores options that are used by groffer for $MANOPT
+ # All options not in %opts are ignored.
+ # Check options used with %Opts_Cmdline_Double.
+ # 0: option used ('' for ignore), 1: has argument or not
+### main_parse_MANOPT()
+ my %opts = ('-7' => ['--ascii', 0],
+ '--ascii' => ['--ascii', 0],
+ '-a' => ['--all', 0],
+ '--all' => ['--all', 0],
+ '-c' => ['', 1],
+ '--catman' => ['', 1],
+ '-e' => ['--extension', 1],
+ '--extension' => ['--extension', 1],
+ '-f' => ['--whatis', 1],
+ '--whatis' => ['--whatis', 1],
+ '-L' => ['--locale', 1],
+ '--locale' => ['--locale', 1],
+ '-m' => ['--systems', 1],
+ '--systems' => ['--systems', 1],
+ '-M' => ['--manpath', 1],
+ '-manpath' => ['--manpath', 1],
+ '--manpath' => ['--manpath', 1],
+ '-p' => ['', 1],
+ '--preprocessor' => ['', 1],
+ '-P' => ['--pager', 1],
+ '-pager' => ['--pager', 1],
+ '-r' => ['', 1],
+ '-prompt' => ['', 1],
+ '-S' => ['--sections', 1],
+ '-sections' => ['--sections', 1],
+ '-T' => ['-T', 1],
+ '--device' => ['-T', 1],
+ '-w' => ['--location', 0],
+ '--where' => ['--location', 0],
+ '--location' => ['--location', 0],
+ );
+
+### main_parse_MANOPT()
+ my ($opt, $has_arg);
+ my $i = 0;
+ my $n = $#Manopt;
+ while ($i <= $n) {
+ my $o = $Manopt[$i];
+ ++$i;
+ # ignore, when not in %opts
+ next unless (exists $opts{$o});
+ if (($o eq '-D') or ($o eq '--default')) {
+ @manopt = ();
+ next;
+ }
+ $opt = $opts{$o}[0];
+ $has_arg = $opts{$o}[1];
+ # ignore, when empty in %opts
+ unless ($opt) {
+ # ignore without argument
+ next unless ($has_arg);
+ # ignore the argument as well
+ ++$i;
+ next;
+ }
+ if ($has_arg) {
+ last if ($i > $n);
+ push @manopt, $opt, $Manopt[$i];
+ ++$i;
+ next;
+ } else {
+ push @manopt, $opt;
+ next;
+ }
+ }
+ @Manopt = @manopt;
+ }
+} # main_parse_MANOPT()
+
+
+########################################################################
+# configuration files, $GROFFER_OPT, and command line, main_config_params()
+########################################################################
+
+my @Options;
+my @Filespecs;
+my @Starting_Conf;
+my @Starting_ARGV = @ARGV;
+sub main_config_params { # handle configuration files
+ # options may not be abbreviated, but must be exact
+ my @conf_args;
+ foreach my $f (@Conf_Files) {
+ if (-s $f) {
+ my $fh;
+ open $fh, "<$f" || next;
+ my $nr = 0;
+ LINE: foreach my $line (<$fh>) {
+ ++ $nr;
+ chomp $line;
+ # remove starting and ending whitespace
+ $line =~ s/^\s+|\s+$//g;
+ # replace whitespace by single space
+ $line =~ s/\s+/ /g;
+ # ignore all lines that do not start with minus
+ next unless $line =~ /^-/;
+ # three minus
+ if ($line =~ /^---/) {
+ warn "Wrong option $line in configuration file $f.\n";
+ next;
+ }
+ if ($line =~ /^--[ =]/) {
+ warn "No option name in `$line' in configuration " .
+ "file $f.\n";
+ next;
+ }
+ push @Starting_Conf, $line;
+ # -- or -
+ if ($line =~ /^--?$/) {
+ warn "`$line' is not allowed in configuration files.\n";
+ next;
+ }
+ ### main_config_params()
+ if ($line =~ /^--/) { # line is long option
+ my ($name, $arg);
+ if ($line =~ /[ =]/) { # has arg on line
+ $line =~ /^(--[^ =]+)[ =] ?(.*)$/;
+ ($name, $arg) = ($1, $2);
+ $arg =~ s/[\'\"]//g;
+ } else { # does not have an argument on line
+ $name = $line;
+ }
+ $name =~ s/[\'\"]//g;
+ unless (exists $Opts_Cmdline_Long{$name}) {
+ # option does not exist
+ warn "Option `$name' does not exist.\n";
+ next LINE;
+ }
+ # option exists
+ if ($Opts_Cmdline_Long{$name}) { # option has arg
+ if (defined $arg) {
+ push @conf_args, $name, $arg;
+ next LINE;
+ } else {
+ warn "Option `$name' needs an argument in " .
+ "configuration file $f\n";
+ next LINE;
+ }
+ } else { # option has no arg
+ if (defined $arg) {
+ warn "Option `$name' may not have an argument " .
+ "in configuration file $f\n";
+ next LINE;
+ } else {
+ push @conf_args, $name;
+ next LINE;
+ }
+ }
+ ### main_config_params()
+ } else { # line is short option or cluster
+ $line =~ s/^-//;
+ while ($line) {
+ $line =~ s/^(.)//;
+ my $opt = "-$1";
+ next if ($opt =~ /\'\"/);
+ if ($opt =~ /- /) {
+ warn "Option `$conf_args[$#conf_args]' does not " .
+ "have an argument.\n";
+ next LINE;
+ }
+ if (exists $Opts_Cmdline_Short{$opt}) {
+ # short opt exists
+ push @conf_args, $opt;
+ if ($Opts_Cmdline_Short{$opt}) { # with arg
+ my $arg = $line;
+ $arg =~ s/^ //;
+ $arg =~ s/\'\"//g;
+ push @conf_args, "$arg";
+ next LINE;
+ } else { # no arg
+ next;
+ }
+ } else { # short option does not exist
+ warn "Wrong short option `-$opt' from " .
+ "configuration. Rest of line ignored.\n";
+ next LINE;
+ }
+ }
+ }
+ }
+ close $fh;
+ }
+ }
+
+### main_config_params()
+ # handle environment variable $GROFFER_OPT
+ my @GROFFER_OPT;
+ if ($ENV{'GROFFER_OPT'}) {
+ @GROFFER_OPT = `sh $File_split_env_sh GROFFER_OPT`;
+ chomp @GROFFER_OPT;
+ }
+
+ # Handle command line parameters together with $GROFFER_OPT.
+ # Options can be abbreviated, with each - as abbreviation place.
+ {
+ my @argv0 = (@GROFFER_OPT, @ARGV);
+ my @argv;
+ my $only_files = 0;
+ my $n = $#argv0; # last element
+ my $n1 = scalar @GROFFER_OPT; # first element of @ARGV
+ my $i = 0; # number of the element
+ my @s = ('the environment variable $GROFFER_OPT', 'the command line');
+ my $j = 0; # index in @s, 0 before $n1, 1 then
+ ELT: while ($i <= $n) {
+ my $elt = $argv0[$i];
+ $j = 1 if $i >= $n1;
+ ++$i;
+ # remove starting and ending whitespace
+ $elt =~ s/^\s+|\s+$//g;
+ # replace whitespace by single space
+ $elt =~ s/\s+/ /g;
+
+ if ($only_files) {
+ push @Filespecs, $elt;
+ next ELT;
+ }
+
+### main_config_params()
+ if ($elt =~ /^-$/) { # -
+ push @Filespecs, $elt;
+ next ELT;
+ }
+ if ($elt =~ /^--$/) { # --
+ $only_files = 1;
+ next ELT;
+ }
+
+ if ($elt =~ /^--[ =]/) { # no option name
+ warn "No option name in `$elt' at $s[$j].\n";
+ next ELT;
+ }
+ if ($elt =~ /^---/) { # wrong with three minus
+ warn "Wrong option `$elt' at $s[$j].\n";
+ next ELT;
+ }
+
+ if ($elt =~ /^--[^-]/) { # long option
+ my ($name, $opt, $abbrev, $arg);
+ if ($elt =~ /[ =]/) { # has arg on elt
+ $elt =~ /^--([^ =]+)[ =] ?(.*)$/;
+ ($name, $arg) = ($1, $2);
+ $opt = "--$name";
+ $abbrev = $name;
+ $arg =~ s/[\'\"]//g;
+ } else { # does not have an argument in the element
+ $opt = $name = $elt;
+ $name =~ s/^--//;
+ $abbrev = $name;
+ }
+### main_config_params()
+ # remove quotes in name
+ $name =~ s/[\'\"]//g;
+ my $match = $name;
+ $match =~ s/-/[^- ]*-/g;
+ ### main_config_params()
+ if (exists $Opts_Cmdline_Long{$opt}) {
+ # option exists exactly
+ } elsif ($Opts_Cmdline_Long_Str =~ / (${match}[^- ]*?) /) {
+ # option is an abbreviation without further -
+ my $n0 = $1;
+ if ($Opts_Cmdline_Long_Str =~
+ / (${match}[^- ]*) .* (${match}[^- ]*) /) {
+ warn "Option name `--$abbrev' is not unique: " .
+ "--$1 --$2 \n";
+ next ELT;
+ }
+ $name = $n0;
+ $opt = "--$n0";
+ } elsif ($Opts_Cmdline_Long_Str =~ / (${match}[^ ]*) /) {
+ # option is an abbreviation with further -
+ my $n0 = $1;
+ if ($Opts_Cmdline_Long_Str =~
+ / (${match}[^ ]*) .* (${match}[^ ]*) /) {
+ warn "Option name `--$abbrev' is not unique: " .
+ "--$1 --$2 \n";
+ next ELT;
+ }
+ $name = $n0;
+ $opt = "--$n0";
+ } else {
+ warn "Option `--$abbrev' does not exist.\n";
+ next ELT;
+ }
+### main_config_params()
+ if ($Opts_Cmdline_Long{$opt}) { # option has arg
+ if (defined $arg) {
+ push @argv, "--$name", $arg;
+ next ELT;
+ } else { # $arg not defined, argument at next element
+ if (($i == $n1) || ($i > $n)) {
+ warn "No argument left for option " .
+ "`$elt' at $s[$j].\n";
+ next ELT;
+ }
+ ### main_config_params()
+ # add argument as next element
+ push @argv, "--$name", $argv0[$i];
+ ++$i;
+ next ELT;
+ } # if (defined $arg)
+ } else { # option has no arg
+ if (defined $arg) {
+ warn "Option `$abbrev' may not have an argument " .
+ "at $s[$j].\n";
+ next ELT;
+ } else {
+ push @argv, "--$name";
+ next ELT;
+ }
+ } # if ($Opts_Cmdline_Long{$opt})
+### main_config_params()
+ } elsif ($elt =~ /^-[^-]/) { # short option or cluster
+ my $cluster = $elt;
+ $cluster =~ s/^-//;
+ while ($cluster) {
+ $cluster =~ s/^(.)//;
+ my $opt = "-$1";
+ if (exists $Opts_Cmdline_Short{$opt}) { # opt exists
+ if ($Opts_Cmdline_Short{$opt}) { # with arg
+ if ($cluster) { # has argument in this element
+ $cluster =~ s/^ //;
+ $cluster =~ s/\'\"//g;
+ # add argument as rest of this element
+ push @argv, $opt, $cluster;
+ next ELT;
+ } else { # argument at next element
+ if (($i == $n1) || ($i > $n)) {
+ warn "No argument left for option " .
+ "`$opt' at $s[$j].\n";
+ next ELT;
+ }
+ ### main_config_params()
+ # add argument as next element
+ push @argv, $opt, $argv0[$i];
+ ++$i;
+ next ELT;
+ }
+ } else { # no arg
+ push @argv, $opt;
+ next;
+ }
+ } else { # short option does not exist
+ warn "Wrong short option `$opt' at $s[$j].\n";
+ next ELT;
+ } # if (exists $Opts_Cmdline_Short{$opt})
+ } # while ($cluster)
+ } else { # not an option, file name
+ push @Filespecs, $elt;
+ next;
+ }
+ }
+### main_config_params()
+ @Options = (@Manopt, @conf_args, @argv);
+ foreach my $i (0..$#Options) {
+ if ( exists $Opts_Cmdline_Double{ $Options[$i] } ) {
+ $Options[$i] = $Opts_Cmdline_Double{ $Options[$i] };
+ }
+ }
+ @Filespecs = ('-') unless (@Filespecs);
+ @ARGV = (@Options, '--', @Filespecs);
+ }
+} # main_config_params()
+
+if (0) {
+ print STDERR "<$_>\n" foreach @ARGV;
+}
+
+
+########################################################################
+# main_parse_params()
+########################################################################
+
+my $i;
+my $n;
+
+$Opt{'XRM'} = [];
+
+sub main_parse_params {
+ $i = 0;
+ $n = $#Options;
+
+ # options that are ignored in this part
+ # shell version of groffer: --debug*, --shell
+ # man options: --catman (only special in man),
+ # --preprocessor (force groff preproc., handled by grog),
+ # --prompt (prompt for less, ignored),
+ # --troff (-mandoc, handled by grog),
+ # --update (inode check, ignored)
+ my %ignored_opts = (
+ '--catman' => 0,
+ '--debug-func' => 0,
+ '--debug-not-func' => 0,
+ '--debug-lm' => 0,
+ '--debug-shell' => 0,
+ '--debug-stacks' => 0,
+ '--debug-user' => 0,
+ '--preprocessor' => 1,
+ '--prompt' => 1,
+ '--shell' => 1,
+ '--troff' => 0,
+ '--update' => 0,
+ );
+
+### main_parse_params()
+ my %long_opts =
+ (
+ '--debug' =>
+ sub { $Debug{$_} = 1 foreach (qw/FILENAMES GROG KEEP PARAMS TMPDIR/); },
+ '--debug-filenames' => sub { $Debug{'FILENAMES'} = 1; },
+ '--debug-grog' => sub { $Debug{'GROG'} = 1; },
+ '--debug-keep' => sub { $Debug{'KEEP'} = 1; $Debug{'PARAMS'} = 1; },
+ '--debug-params' => sub { $Debug{'PARAMS'} = 1; },
+ '--debug-tmpdir' => sub { $Debug{'TMPDIR'} = 1; },
+ '--help' => sub { &usage(); $Opt{'DO_NOTHING'} = 1; },
+ '--source' => sub { $Opt{'MODE'} = 'source'; },
+ '--device' =>
+ sub { $Opt{'DEVICE'} = &_get_arg();
+ my %modes = ( 'dvi'=> 'dvi',
+ 'html' => 'html',
+ 'lbp' => 'groff',
+ 'lj4' => 'groff',
+ 'ps' => 'ps',
+ 'ascii' => 'tty',
+ 'cp1047' => 'tty',
+ 'latin1' => 'tty',
+ 'utf8' => 'tty',
+ );
+ if ($Opt{'DEVICE'} =~ /^X.*/) {
+ $Opt{'MODE'} = 'x';
+ } elsif ( exists $modes{ $Opt{'DEVICE'} } ) {
+ if ( $modes{ $Opt{'DEVICE'} } eq 'tty' ) {
+ $Opt{'MODE'} = 'tty'
+ unless ($Opt{'MODE'} eq 'text');
+ } else {
+ $Opt{'MODE'} = $modes{ $Opt{'DEVICE'} };
+ }
+ } else {
+ # for all elements not in %modes
+ $Opt{'MODE'} = 'groff';
+ }
+ },
+### main_parse_params()
+ '--version' => sub { &version(); $Opt{'DO_NOTHING'} = 1; },
+ '--intermediate-output' => sub { $Opt{'Z'} = 1; },
+ '--all' => sub { $Opt{'ALL'} = 1; },
+ '--apropos' => # run apropos
+ sub { $Opt{'APROPOS'} = 1;
+ delete $Opt{'APROPOS_SECTIONS'};
+ delete $Opt{'WHATIS'}; },
+ '--apropos-data' => # run apropos for data sections
+ sub { $Opt{'APROPOS'} = 1;
+ $Opt{'APROPOS_SECTIONS'} = '457';
+ delete $Opt{'WHATIS'}; },
+ '--apropos-devel' => # run apropos for devel sections
+ sub { $Opt{'APROPOS'} = 1;
+ $Opt{'APROPOS_SECTIONS'} = '239';
+ delete $Opt{'WHATIS'}; },
+ '--apropos-progs' => # run apropos for prog sections
+ sub { $Opt{'APROPOS'} = 1;
+ $Opt{'APROPOS_SECTIONS'} = '168';
+ delete $Opt{'WHATIS'}; },
+ '--ascii' =>
+ sub { push @Addopts_Groff, '-mtty-char';
+ $Opt{'MODE'} = 'text' unless $Opt{'MODE'}; },
+ '--auto' => # the default automatic mode
+ sub { delete $Opt{'MODE'}; },
+ '--bordercolor' => # border color for viewers, arg
+ sub { $Opt{'BD'} = &_get_arg(); },
+ '--background' => # background color for viewers, arg
+ sub { $Opt{'BG'} = &_get_arg(); },
+### main_parse_params()
+ '--borderwidth' => # border width for viewers, arg
+ sub { $Opt{'BW'} = &_get_arg(); },
+ '--default' => # reset variables to default
+ sub { %Opt = (); },
+ '--default-modes' => # sequence of modes in auto mode; arg
+ sub { $Opt{'DEFAULT_MODES'} = &_get_arg(); },
+ '--display' => # set X display, arg
+ sub { $Opt{'DISPLAY'} = &_get_arg(); },
+ '--do-nothing' => sub { $Opt{'DO_NOTHING'} = 1; },
+ '--dvi' => sub { $Opt{'MODE'} = 'dvi'; },
+ '--dvi-viewer' => # viewer program for dvi mode; arg
+ sub { $Opt{'VIEWER_DVI'} = &_get_arg(); },
+ '--extension' => # the extension for man pages, arg
+ sub { $Opt{'EXTENSION'} = &_get_arg(); },
+ '--foreground' => # foreground color for viewers, arg
+ sub { $Opt{'FG'} = &_get_arg(); },
+ '--font' => # set font for viewers, arg
+ sub { $Opt{'FN'} = &_get_arg(); },
+ '--geometry' => # window geometry for viewers, arg
+ sub { $Opt{'GEOMETRY'} = &_get_arg(); },
+ '--groff' => sub { $Opt{'MODE'} = 'groff'; },
+ '--html' => sub { $Opt{'MODE'} = 'html'; },
+ '--html-viewer' => # viewer program for html mode; arg
+ sub { $Opt{'VIEWER_HTML'} = &_get_arg(); },
+ '--iconic' => # start viewers as icons
+ sub { $Opt{'ICONIC'} = 1; },
+ '--locale' => # set language for man pages, arg
+ # argument is xx[_territory[.codeset[@modifier]]] (ISO 639,...)
+ sub { $Opt{'LANG'} = &_get_arg(); },
+ '--local-file' => # force local files; same as `--no-man'
+ sub { delete $Man{'ENABLE'}; delete $Man{'FORCE'}; },
+ '--location' => # print file locations to stderr
+ sub { $Opt{'LOCATION'} = 1; },
+### main_parse_params()
+ '--man' => # force all file params to be man pages
+ sub { $Man{'ENABLE'} = 1; $Man{'FORCE'} = 1; },
+ '--manpath' => # specify search path for man pages, arg
+ # arg is colon-separated list of directories
+ sub { $Opt{'MANPATH'} = &_get_arg(); },
+ '--mode' => # display mode
+ sub { my $arg = &_get_arg();
+ my %modes = ( '' => '',
+ 'auto' => '',
+ 'groff' => 'groff',
+ 'html' => 'html',
+ 'www' => 'html',
+ 'dvi' => 'dvi',
+ 'pdf' => 'pdf',
+ 'ps' => 'ps',
+ 'text' => 'text',
+ 'tty' => 'tty',
+ 'X' => 'x',
+ 'x' => 'x',
+ 'Q' => 'source',
+ 'source' => 'source',
+ );
+ if ( exists $modes{$arg} ) {
+ if ( $modes{$arg} ) {
+ $Opt{'MODE'} = $modes{$arg};
+ } else {
+ delete $Opt{'MODE'};
+ }
+ } else {
+ warn "Unknown mode in `$arg' for --mode\n";
+ }
+ },
+### main_parse_params()
+ '--no-location' => # disable former call to `--location'
+ sub { delete $Opt{'LOCATION'}; },
+ '--no-man' => # disable search for man pages
+ sub { delete $Man{'ENABLE'}; delete $Man{'FORCE'}; },
+ '--no-special' => # disable some special former calls
+ sub { delete $Opt{'ALL'}; delete $Opt{'APROPOS'};
+ delete $Opt{'WHATIS'}; },
+ '--pager' => # set paging program for tty mode, arg
+ sub { $Opt{'PAGER'} = &_get_arg(); },
+ '--pdf' => sub { $Opt{'MODE'} = 'pdf'; },
+ '--pdf-viewer' => # viewer program for pdf mode; arg
+ sub { $Opt{'VIEWER_PDF'} = &_get_arg(); },
+ '--print' => # print argument, for argument test
+ sub { my $arg = &_get_arg; print STDERR "$arg\n"; },
+ '--ps' => sub { $Opt{'MODE'} = 'ps'; },
+ '--ps-viewer' => # viewer program for ps mode; arg
+ sub { $Opt{'VIEWER_PS'} = &_get_arg(); },
+ '--resolution' => # set resolution for X devices, arg
+ sub { my $arg = &_get_arg();
+ my %res = ( '75' => 75,
+ '75dpi' => 75,
+ '100' => 100,
+ '100dpi' => 100,
+ );
+ if (exists $res{$arg}) {
+ $Opt{'RESOLUTION'} = $res{$arg};
+ } else {
+ warn "--resolution allows only 75, 75dpi, " .
+ "100, 100dpi as argument.\n";
+ }
+ },
+### main_parse_params()
+ '--rv' => sub { $Opt{'RV'} = 1; },
+ '--sections' => # specify sections for man pages, arg
+ # arg is a `:'-separated (colon) list of section names
+ sub { my $arg = &_get_arg();
+ my @arg = split /:/, $arg;
+ my $s;
+ foreach (@arg) {
+ /^(.)/;
+ my $c = $1;
+ if ($Man{'AUTO_SEC_CHARS'} =~ /$c/) {
+ $s .= $c;
+ } else {
+ warn "main_parse_params(): not a man section `$c';";
+ }
+ }
+ $Opt{'SECTIONS'} = $s; },
+ '--systems' => # man pages for different OS's, arg
+ # argument is a comma-separated list
+ sub { $Opt{'SYSTEMS'} = &_get_arg(); },
+ '--text' => # text mode without pager
+ sub { $Opt{'MODE'} = 'text'; },
+ '--title' => # title for X viewers; arg
+ sub { my $arg = &_get_arg();
+ if ($arg) {
+ if ( $Opt{'TITLE'} ) {
+ $Opt{'TITLE'} = "$Opt{'TITLE'} $arg";
+ } else {
+ $Opt{'TITLE'} = $arg;
+ }
+ }
+ },
+ '--tty' => # tty mode, text with pager
+ sub { $Opt{'MODE'} = 'tty'; },
+ '--to-stdout' => # print mode file without display
+ sub { $Opt{'STDOUT'} = 1; },
+ '--text-device' => # device for tty mode; arg
+ sub { $Opt{'TEXT_DEVICE'} = &_get_arg(); },
+ '--whatis' => sub { delete $Opt{'APROPOS'}; $Opt{'WHATIS'} = 1; },
+ '--x' => sub { $Opt{'MODE'} = 'x'; },
+### main_parse_params()
+ '--xrm' => # pass X resource string, arg
+ sub { my $arg = &_get_arg(); push @{$Opt{'XRM'}}, $arg if $arg; },
+ '--x-viewer' => # viewer program for x mode; arg
+ sub { $Opt{'VIEWER_X'} = &_get_arg(); },
+ );
+
+ my %short_opts = (
+ '-V' => sub { $Opt{'V'} = 1; },
+ '-X' => sub { $Opt{'X'} = 1; },
+ );
+
+ if (0) {
+ # check if all options are handled in parse parameters
+
+ #short options
+ my %these_opts = (%ignored_opts, %short_opts, %Opts_Groff_Short,
+ %Opts_Cmdline_Double);
+ foreach my $key (keys %Opts_Cmdline_Short) {
+ warn "unused option: $key" unless exists $these_opts{$key};
+ }
+
+ # long options
+ %these_opts = (%ignored_opts, %long_opts, %Opts_Cmdline_Double);
+ foreach my $key (keys %Opts_Cmdline_Long) {
+ warn "unused option: $key" unless exists $these_opts{$key};
+ }
+ } # if (0)
+
+### main_parse_params()
+ OPTION: while ($i <= $n) {
+ my $opt = $Options[$i];
+ ++$i;
+ if ($opt =~ /^-([^-])$/) { # single minus for short option
+ if (exists $short_opts{$opt}) { # short option handled by hash
+ $short_opts{$opt}->();
+ next OPTION;
+ } else { # $short_opts{$opt} does not exist
+ my $c = $1; # the option character
+ next OPTION unless $c;
+ if ( exists $Opts_Groff_Short{ $opt } ) { # groff short option
+ if ( $Opts_Groff_Short{ $opt } ) { # option has argument
+ my $arg = $Options[$i];
+ ++$i;
+ push @Addopts_Groff, $opt, $arg;
+ next OPTION;
+ } else { # no argument for this option
+ push @Addopts_Groff, $opt;
+ next OPTION;
+ }
+ } elsif ( exists $Opts_Cmdline_Short{ $opt } ) {
+ # is a groffer short option
+ warn "Groffer option $opt not handled " .
+ "in parameter parsing";
+ } else {
+ warn "$opt is not a groffer option.\n";
+ }
+ } # if (exists $short_opts{$opt})
+ } # if ($opt =~ /^-([^-])$/)
+ # Now it is a long option
+
+ # handle ignored options
+ if ( exists $ignored_opts{ $opt } ) {
+ ++$i if ( $ignored_opts{ $opt } );
+ next OPTION;
+ }
+### main_parse_params()
+
+ # handle normal long options
+ if (exists $long_opts{$opt}) {
+ $long_opts{$opt}->();
+ } else {
+ warn "Unknown option $opt.\n";
+ }
+ next OPTION;
+ } # while ($i <= $n)
+
+ if ($Debug{'PARAMS'}) {
+ print STDERR '$MANOPT: ' . "$ENV{'MANOPT'}\n" if $ENV{'MANOPT'};
+ foreach (@Starting_Conf) {
+ print STDERR "configuration: $_\n";
+ }
+ print STDERR '$GROFFER_OPT: ' . "$ENV{'GROFFER_OPT'}\n"
+ if $ENV{'GROFFER_OPT'};
+ print STDERR "command line: @Starting_ARGV\n";
+ print STDERR "parameters: @ARGV\n";
+ }
+
+ if ( $Opt{'WHATIS'} ) {
+ die "main_parse_params(): cannot handle both `whatis' and `apropos';"
+ if $Opt{'APROPOS'};
+ $Man{'ALL'} = 1;
+ delete $Opt{'APROPOS_SECTIONS'};
+ }
+
+ if ( $Opt{'DO_NOTHING'} ) {
+ exit;
+ }
+
+ if ( $Opt{'DEFAULT_MODES'} ) {
+ @Default_Modes = split /,/, $Opt{'DEFAULT_MODES'};
+ }
+} # main_parse_params()
+
+
+sub _get_arg {
+ if ($i > $n) {
+ die '_get_arg(): No argument left for last option;';
+ }
+ my $arg = $Options[$i];
+ ++$i;
+ $arg;
+} # _get_arg() of main_parse_params()
+
+
+########################################################################
+# main_set_mode()
+########################################################################
+
+my $Viewer_Background;
+my $PDF_Did_Not_Work;
+my $PDF_Has_gs;
+my $PDF_Has_ps2pdf;
+my %Display = ('MODE' => '',
+ 'PROG' => '',
+ 'ARGS' => ''
+ );
+
+sub main_set_mode {
+ my @modes;
+
+ # set display
+ $ENV{'DISPLAY'} = $Opt{'DISPLAY'} if $Opt{'DISPLAY'};
+
+ push @Addopts_Groff, '-V' if $Opt{'V'};
+
+ if ( $Opt{'X'} ) {
+ $Display{'MODE'} = 'groff';
+ push @Addopts_Groff, '-X';
+ }
+
+ if ( $Opt{'Z'} ) {
+ $Display{'MODE'} = 'groff';
+ push @Addopts_Groff, '-Z';
+ }
+
+ $Display{'MODE'} = 'groff' if $Opt{'MODE'} and $Opt{'MODE'} eq 'groff';
+
+ return 1 if $Display{'MODE'} and $Display{'MODE'} eq 'groff';
+
+### main_set_mode()
+ if ($Opt{'MODE'}) {
+ if ($Opt{'MODE'} =~ /^(source|text|tty)$/) {
+ $Display{'MODE'} = $Opt{'MODE'};
+ return 1;
+ }
+ $Display{'MODE'} = $Opt{'MODE'} if $Opt{'MODE'} =~ /^html$/;
+ @modes = ($Opt{'MODE'});
+ } else { # empty mode
+ if ($Opt{'DEVICE'}) {
+ if ($Opt{'DEVICE'} =~ /^X/) {
+ &is_X() || die "no X display found for device $Opt{'DEVICE'}";
+ $Display{'MODE'} = 'x';
+ return 1;
+ }
+ ;
+ if ($Opt{'DEVICE'} =~ /^(ascii|cp1047|latin1|utf8)$/) {
+ $Display{'MODE'} ne 'text' and $Display{'MODE'} = 'tty';
+ return 1;
+ }
+ ;
+ unless (&is_X) {
+ $Display{'MODE'} = 'tty';
+ return 1;
+ }
+ } # check device
+ @modes = @Default_Modes;
+ } # check mode
+
+### main_set_mode()
+ LOOP: foreach my $m (@modes) {
+ $Viewer_Background = 0;
+ if ($m =~ /^(test|tty|X)$/) {
+ $Display{'MODE'} = $m;
+ return 1;
+ } elsif ($m eq 'pdf') {
+ next LOOP if $PDF_Did_Not_Work;
+ $PDF_Has_gs = &where_is_prog('gs') ? 1 : 0
+ unless (defined $PDF_Has_gs);
+ $PDF_Has_ps2pdf = &where_is_prog('ps2pdf') ? 1 : 0
+ unless (defined $PDF_Has_ps2pdf);
+ if ( (! $PDF_Has_gs) and (! $PDF_Has_ps2pdf) ) {
+ $PDF_Did_Not_Work = 1;
+ next LOOP;
+ }
+
+ if (&_get_prog_args($m)) {
+ return 1;
+ } else {
+ $PDF_Did_Not_Work = 1;
+ next LOOP;
+ }
+ } else { # other modes
+ &_get_prog_args($m) ? return 1 : next LOOP;
+ } # if $m
+ } # LOOP: foreach
+ die 'set mode: no suitable display mode found under ' .
+ join(', ', @modes) . ';' unless $Display{'MODE'};
+ die 'set mode: no viewer available for mode ' . $Display{'MODE'} . ';'
+ unless $Display{'PROG'};
+ 0;
+} # main_set_mode()
+
+
+########################################################################
+# functions to main_set_mode()
+########################################################################
+
+##########
+# _get_prog_args(<MODE>)
+#
+# Simplification for loop in set mode.
+#
+# Globals in/out: $Viewer_Background
+# Globals in : $Opt{VIEWER_<MODE>}, $Viewer_X{<MODE>},
+# $Viewer_tty{<MODE>}
+#
+sub _get_prog_args {
+ my $n = @_;
+ die "_get_prog_args(): one argument is needed; you used $n;"
+ unless $n == 1;
+
+ my $mode = lc($_[0]);
+ my $MODE = uc($mode);
+
+ my $xlist = $Viewer_X{$MODE};
+ my $ttylist = $Viewer_tty{$MODE};
+
+ my $vm = "VIEWER_${MODE}";
+ my $opt = $Opt{$vm};
+
+ if ($opt) {
+ my %prog = where_is_prog $opt;
+ my $prog_ref = \%prog;
+ unless (%prog) {
+ warn "_get_prog_args(): `$opt' is not an existing program;";
+ return 0;
+ }
+
+ # $prog from $opt is an existing program
+
+### _get_prog_args() of main_set_mode()
+ if (&is_X) {
+ if ( &_check_prog_on_list($prog_ref, $xlist) ) {
+ $Viewer_Background = 1;
+ } else {
+ $Viewer_Background = 0;
+ &_check_prog_on_list($prog_ref, $ttylist);
+ }
+ } else { # is not X
+ $Viewer_Background = 0;
+ &_check_prog_on_list($prog_ref, $ttylist);
+ } # if is X
+ } else { # $opt is empty
+ $Viewer_Background = 0;
+ my $x;
+ if (&is_X) {
+ $x = &_get_first_prog($xlist);
+ $Viewer_Background = 1 if $x;
+ } else { # is not X
+ $x = &_get_first_prog($ttylist);
+ } # test on X
+ $Display{'MODE'} = $mode if $x;
+ return $x;
+ }
+ $Display{'MODE'} = $mode;
+ return 1;
+} # _get_prog_args() of main_set_mode()
+
+
+##########
+# _get_first_prog(<prog_list_ref>)
+#
+# Retrieve from the elements of the list in the argument the first
+# existing program in $PATH.
+#
+# Local function of main_set_mode().
+#
+# Return : `0' if not a part of the list, `1' if found in the list.
+#
+sub _get_first_prog {
+ my $n = @_;
+ die "_get_first_prog(): one argument is needed; you used $n;"
+ unless $n == 1;
+
+ foreach my $i (@{$_[0]}) {
+ next unless $i;
+ my %prog = &where_is_prog($i);
+ if (%prog) {
+ $Display{'PROG'} = $prog{'fullname'};
+ $Display{'ARGS'} = $prog{'args'};
+ return 1;
+ }
+ }
+ return 0;
+} # _get_first_prog() of main_set_mode()
+
+
+##########
+# _check_prog_on_list (<prog-hash-ref> <prog_list_ref>)
+#
+# Check whether the content of <prog-hash-ref> is in the list
+# <prog_list_ref>.
+# The globals are set correspondingly.
+#
+# Local function for main_set_mode().
+#
+# Arguments: 2
+#
+# Return : `0' if not a part of the list, `1' if found in the list.
+# Output : none
+#
+# Globals in : $Viewer_X{<MODE>}, $Viewer_tty{<MODE>}
+# Globals in/out: $Display{'PROG'}, $Display{'ARGS'}
+#
+sub _check_prog_on_list {
+ my $n = @_;
+ die "_get_first_prog(): 2 arguments are needed; you used $n;"
+ unless $n == 2;
+
+ my %prog = %{$_[0]};
+
+ $Display{'PROG'} = $prog{'fullname'};
+ $Display{'ARGS'} = $prog{'args'};
+
+ foreach my $i (@{$_[1]}) {
+ my %p = &where_is_prog($i);
+ next unless %p;
+ next unless $Display{'PROG'} eq $p{'fullname'};
+ if ($p{'args'}) {
+ if ($Display{'ARGS'}) {
+ $Display{'ARGS'} = $p{'args'};
+ } else {
+ $Display{'ARGS'} = "$p{'args'} $Display{'ARGS'}";
+ }
+ } # if args
+ return 1;
+ } # foreach $i
+ # prog was not in the list
+ return 0;
+} # _check_prog_on_list() of main_set_mode()
+
+
+########################################################################
+# groffer temporary directory, main_temp()
+########################################################################
+
+sub main_temp {
+ my $template = 'groffer_' . "$$" . '_XXXX';
+ foreach ($ENV{'GROFF_TMPDIR'}, $ENV{'TMPDIR'}, $ENV{'TMP'}, $ENV{'TEMP'},
+ $ENV{'TEMPDIR'}, File::Spec->catfile($ENV{'HOME'}, 'tmp')) {
+ if ($_ && -d $_ && -w $_) {
+ if ($Debug{'KEEP'}) {
+ eval { $tmpdir = tempdir( $template, DIR => "$_" ); };
+ } else {
+ eval { $tmpdir = tempdir( $template,
+ CLEANUP => 1, DIR => "$_" ); };
+ }
+ last if $tmpdir;
+ }
+ }
+ $tmpdir = tempdir( $template, CLEANUP => 1, DIR => File::Spec->tmpdir )
+ unless ($tmpdir);
+
+ # see Lerning Perl, page 205, or Programming Perl, page 413
+ # $SIG{'INT'} is for Ctrl-C interruption
+ $SIG{'INT'} = sub { &clean_up(); die "interrupted..."; };
+ $SIG{'QUIT'} = sub { &clean_up(); die "quit..."; };
+
+ if ($Debug{'TMPDIR'}) {
+ if ( $Debug{'KEEP'}) {
+ print STDERR "temporary directory is kept: $tmpdir\n";
+ } else {
+ print STDERR "temporary directory will be cleaned: $tmpdir\n";
+ }
+ }
+
+ # further argument: SUFFIX => '.sh'
+ if ($Debug{'KEEP'}) {
+ ($fh_cat, $tmp_cat) = tempfile(',cat_XXXX', DIR => $tmpdir);
+ ($fh_stdin, $tmp_stdin) = tempfile(',stdin_XXXX', DIR => $tmpdir);
+ } else {
+ ($fh_cat, $tmp_cat) = tempfile(',cat_XXXX', UNLINK => 1,
+ DIR => $tmpdir);
+ ($fh_stdin, $tmp_stdin) = tempfile(',stdin_XXXX', UNLINK => 1,
+ DIR => $tmpdir);
+ }
+} # main_temp()
+
+
+########################################################################
+# tmp functions and compression
+########################################################################
+
+########################################################################
+# further functions needed for main_do_fileargs()
+########################################################################
+
+my @REG_TITLE = ();
+
+##########
+# register_file(<filename>)
+#
+# Write a found file and register the title element.
+#
+# Arguments: 1: a file name
+# Output: none
+#
+sub register_file {
+ my $n = @_;
+ die "register_file(): one argument is needed; you used $n;"
+ unless $n == 1;
+ die 'register_file(): file name is empty;' unless $_[0];
+
+ if ($_[0] eq '-') {
+ &to_tmp($tmp_stdin) && &register_title('stdin');
+ } else {
+ &to_tmp($_[0]) && &register_title($_[0]);
+ }
+ 1;
+} # register_file()
+
+
+##########
+# register_title(<filespec>)
+#
+# Create title element from <filespec> and append to $_REG_TITLE_LIST.
+# Basename is created.
+#
+# Globals in/out: @REG_TITLE
+#
+# Variable prefix: rt
+#
+sub register_title {
+ my $n = @_;
+ die "register_title(): one argument is needed; you used $n;"
+ unless $n == 1;
+ return 1 unless $_[0];
+
+ return 1 if scalar @REG_TITLE > 3;
+
+ my $title = &get_filename($_[0]);
+ $title =~ s/\s/_/g;
+ $title =~ s/\.bz2$//g;
+ $title =~ s/\.gz$//g;
+ $title =~ s/\.Z$//g;
+
+ if ($Debug{'FILENAMES'}) {
+ if ($_[0] eq 'stdin') {
+ print STDERR "register_title(): file title is stdin\n";
+ } else {
+ print STDERR "register_title(): file title is $title\n";
+ }
+ } # if ($Debug{'FILENAMES'})
+
+ return 1 unless $title;
+ push @REG_TITLE, $title;
+ 1;
+} # register_title()
+
+
+##########
+# save_stdin()
+#
+# Store standard input to temporary file (with decompression).
+#
+sub save_stdin {
+ my ($fh_input, $tmp_input);
+ $tmp_input = File::Spec->catfile($tmpdir, ',input');
+ open $fh_input, ">$tmp_input" or
+ die "save_stdin(): could not open $tmp_input";
+ foreach (<STDIN>) {
+ print $fh_input $_;
+ }
+ close $fh_input;
+ open $fh_stdin, ">$tmp_stdin" or
+ die "save_stdin(): could not open $tmp_stdin";
+ foreach ( &cat_z("$tmp_input") ) {
+ print $fh_stdin "$_";
+ }
+ close $fh_stdin;
+ unlink $tmp_input unless $Debug{'KEEP'};
+} # save_stdin()
+
+
+########################################################################
+# main_do_fileargs()
+########################################################################
+
+sub main_do_fileargs {
+ &special_setup();
+ if ($Opt{'APROPOS'}) {
+ if ($No_Filespecs) {
+ &apropos_filespec();
+ return 1;
+ }
+ } else {
+ foreach (@Filespecs) {
+ if (/^-$/) {
+ &save_stdin();
+ last;
+ }
+ } # foreach (@Filespecs)
+ } # if ($Opt{'APROPOS'})
+
+ my $section = '';
+ my $ext = '';
+ my $twoargs = 0;
+ my $filespec;
+ my $former_arg;
+
+ FILESPEC: foreach (@Filespecs) {
+ $filespec = $_;
+ $Filespec_Arg = $_;
+ $Filespec_Is_Man = 0;
+ $Manspec = '';
+ $Special_Filespec = 0;
+
+ next FILESPEC unless $filespec;
+
+### main_do_fileargs()
+ if ($twoargs) { # second run
+ $twoargs = 0;
+ # $section and $ext are kept from earlier run
+ my $h = { 'name' => $filespec, 'sec' => $section, 'ext' => $ext };
+ &man_setup();
+ if ( &is_man($h) ) {
+ $Filespec_Arg = "$former_arg $Filespec_Arg";
+ &special_filespec();
+ $Filespec_Is_Man = 1;
+ &man_get($h);
+ next FILESPEC;
+ } else {
+ warn "main_do_fileargs(): $former_arg is neither a file nor a " .
+ "man page nor a section argument for $filespec;";
+ }
+ }
+ $twoargs = 0;
+
+ if ( $Opt{'APROPOS'} ) {
+ &apropos_filespec();
+ next FILESPEC;
+ }
+
+ if ($filespec eq '-') {
+ &register_file('-');
+ &special_filespec();
+ next FILESPEC;
+ } elsif ( &get_filename($filespec) ne $filespec ) { # path with dir
+ &special_filespec();
+ if (-f $filespec && -r $filespec) {
+ &register_file($filespec)
+ } else {
+ warn "main_do_fileargs: the argument $filespec is not a file;";
+ }
+ next FILESPEC;
+ } else { # neither `-' nor has dir
+ # check whether filespec is an existing file
+ unless ( $Man{'FORCE'} ) {
+ if (-f $filespec && -r $filespec) {
+ &special_filespec();
+ &register_file($filespec);
+ next FILESPEC;
+ }
+ }
+ } # if ($filespec eq '-')
+
+### main_do_fileargs()
+ # now it must be a man page pattern
+
+ if ($Macro_Pkg and $Macro_Pkg ne '-man') {
+ warn "main_do_fileargs(): $filespec is not a file, " .
+ "man pages are ignored due to $Macro_Pkg;";
+ next FILESPEC;
+ }
+
+ # check for man page
+ &man_setup();
+ unless ( $Man{'ENABLE'} ) {
+ warn "main_do_fileargs(): the argument $filespec is not a file;";
+ next FILESPEC;
+ }
+ my $errmsg;
+ if ( $Man{'FORCE'} ) {
+ $errmsg = 'is not a man page';
+ } else {
+ $errmsg = 'is neither a file nor a man page';
+ }
+
+ $Filespec_Is_Man = 1;
+
+### main_do_fileargs()
+ # test filespec with `man:...' or `...(...)' on man page
+
+ my @names = ($filespec);
+ if ($filespec =~ /^man:(.*)$/) {
+ push @names, $1;
+ }
+
+ foreach my $i (@names) {
+ next unless $i;
+ my $h = { 'name' => $i };
+ if ( &is_man($h) ) {
+ &special_filespec();
+ &man_get($h);
+ next FILESPEC;
+ }
+ if ( $i =~ /^(.*)\(([$Man{'AUTO_SEC_CHARS'}])(.*)\)$/ ) {
+ $h = { 'name' => $1, 'sec' => $2, 'ext' => $3 };
+ if ( &is_man($h) ) {
+ &special_filespec();
+ &man_get($h);
+ next FILESPEC;
+ }
+ } # if //
+ if ( $i =~ /^(.*)\.([$Man{'AUTO_SEC_CHARS'}])(.*)$/ ) {
+ $h = { 'name' => $1, 'sec' => $2, 'ext' => $3 };
+ if ( &is_man($h) ) {
+ &special_filespec();
+ &man_get($h);
+ next FILESPEC;
+ }
+ } # if //
+ } # foreach (@names)
+
+### main_do_fileargs()
+ # check on "s name", where "s" is a section with or without an extension
+ if ($filespec =~ /^([$Man{'AUTO_SEC_CHARS'}])(.*)$/) {
+ unless ( $Man{'ENABLE'} ) {
+ warn "main_do_fileargs(): $filespec $errmsg;";
+ next FILESPEC;
+ }
+ $twoargs = 1;
+ $section = $1;
+ $ext = $2;
+ $former_arg = $filespec;
+ next FILESPEC;
+ } else {
+ warn "main_do_fileargs(): $filespec $errmsg;";
+ next FILESPEC;
+ }
+ } # foreach (@Filespecs)
+
+ if ($twoargs) {
+ warn "main_do_fileargs(): no filespec arguments left for second run;";
+ return 0;
+ }
+ 1;
+} # main_do_fileargs()
+
+
+########################################################################
+# main_set_resources()
+########################################################################
+
+##########
+# main_set_resources ()
+#
+# Determine options for setting X resources with $_DISPLAY_PROG.
+#
+# Globals: $Display{PROG}, $Output_File_Name
+#
+sub main_set_resources {
+ # $prog viewer program
+ # $rl resource list
+ unlink $tmp_stdin unless $Debug{'KEEP'};
+ $Output_File_Name = '';
+
+ my @title = @REG_TITLE;
+ @title = ($Opt{'TITLE'}) unless @title;
+ @title = () unless @title;
+
+ foreach my $n (@title) {
+ next unless $n;
+ $n =~ s/^,+// if $n =~ /^,/;
+ next unless $n;
+ $Output_File_Name = $Output_File_Name . ',' if $Output_File_Name;
+ $Output_File_Name = "$Output_File_Name$n";
+ } # foreach (@title)
+
+ $Output_File_Name =~ s/^,+//;
+ $Output_File_Name = '-' unless $Output_File_Name;
+ $Output_File_Name = File::Spec->catfile($tmpdir, $Output_File_Name);
+
+### main_set_resources()
+ unless ($Display{'PROG'}) { # for example, for groff mode
+ $Display{'ARGS'} = '';
+ return 1;
+ }
+
+ my %h = &where_is_prog($Display{'PROG'});
+ my $prog = $h{'file'};
+ if ($Display{'ARGS'}) {
+ $Display{'ARGS'} = "$h{'args'} $Display{'ARGS'}";
+ } else {
+ $Display{'ARGS'} = $h{'args'};
+ }
+
+ my @rl = ();
+
+ if ($Opt{'BD'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-bd', $Opt{'BD'};
+ }
+ }
+
+ if ($Opt{'BG'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-bg', $Opt{'BG'};
+ } elsif ($prog eq 'kghostview') {
+ push @rl, '--bg', $Opt{'BG'};
+ } elsif ($prog eq 'xpdf') {
+ push @rl, '-papercolor', $Opt{'BG'};
+ }
+ }
+
+### main_set_resources()
+ if ($Opt{'BW'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-bw', $Opt{'BW'};
+ }
+ }
+
+ if ($Opt{'FG'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-fg', $Opt{'FG'};
+ } elsif ($prog eq 'kghostview') {
+ push @rl, '--fg', $Opt{'FG'};
+ }
+ }
+
+ if ($Opt{'FN'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-fn', $Opt{'FN'};
+ } elsif ($prog eq 'kghostview') {
+ push @rl, '--fn', $Opt{'FN'};
+ }
+ }
+
+ if ($Opt{'GEOMETRY'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-geometry', $Opt{'GEOMETRY'};
+ } elsif ($prog eq 'kghostview') {
+ push @rl, '--geometry', $Opt{'GEOMETRY'};
+ }
+ }
+
+### main_set_resources()
+ if ($Opt{'RESOLUTION'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-resolution', $Opt{'RESOLUTION'};
+ } elsif ($prog eq 'xpdf') {
+ if ($Display{'PROG'} !~ / -z/) { # if xpdf does not have option -z
+ if ($Default_Resolution == 75) {
+ push @rl, '-z', 104;
+ } elsif ($Default_Resolution == 100) { # 72dpi is '100'
+ push @rl, '-z', 139;
+ }
+ }
+ } # if $prog
+ } else { # empty $Opt{RESOLUTION}
+ $Opt{'RESOLUTION'} = $Default_Resolution;
+ if ($prog =~ /^(gxditview|xditview)$/) {
+ push @rl, '-resolution', $Default_Resolution;
+ } elsif ($prog eq 'xpdf') {
+ if ($Display{'PROG'} !~ / -z/) { # if xpdf does not have option -z
+ if ($Default_Resolution == 75) {
+ push @rl, '-z', 104;
+ } elsif ($Default_Resolution == 100) { # 72dpi is '100'
+ push @rl, '-z', 139;
+ }
+ }
+ } # if $prog
+ } # if $Opt{RESOLUTION}
+
+ if ($Opt{'ICONIC'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-iconic';
+ }
+ }
+
+### main_set_resources()
+ if ($Opt{'RV'}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
+ push @rl, '-rv';
+ }
+ }
+
+ if (@{$Opt{'XRM'}}) {
+ if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi|xpdf)$/) {
+ foreach (@{$Opt{'XRM'}}) {
+ push @rl, '-xrm', $_;
+ }
+ }
+ }
+
+ if (@title) {
+ if ($prog =~ /^(gxditview|xditview)$/) {
+ push @rl, '-title', $Output_File_Name;
+ }
+ }
+
+ my $args = join ' ', @rl;
+ if ($Display{'ARGS'}) {
+ $Display{'ARGS'} = "$args $Display{'ARGS'}";
+ } else {
+ $Display{'ARGS'} = $args;
+ }
+
+ 1;
+} # main_set_resources()
+
+
+########################################################################
+# set resources
+########################################################################
+
+my $groggy;
+my $modefile;
+my $addopts;
+
+##########
+# main_display ()
+#
+# Do the actual display of the whole thing.
+#
+# Globals:
+# in: $Display{MODE}, $Opt{DEVICE}, @Addopts_Groff,
+# $fh_cat, $tmp_cat, $Opt{PAGER}, $Output_File_Name
+#
+sub main_display {
+ $addopts = join ' ', @Addopts_Groff;
+
+ if (-z $tmp_cat) {
+ warn "groffer: empty input\n";
+ &clean_up();
+ return 1;
+ }
+
+ $modefile = $Output_File_Name;
+
+ # go to the temporary directory to be able to access internal data files
+ chdir $tmpdir;
+
+### main_display()
+ SWITCH: foreach ($Display{'MODE'}) {
+ /^groff$/ and do {
+ push @Addopts_Groff, "-T$Opt{'DEVICE'}" if $Opt{'DEVICE'};
+ $addopts = join ' ', @Addopts_Groff;
+ $groggy = `cat $tmp_cat | grog`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ &_do_opt_V();
+ unlink $modefile;
+ rename $tmp_cat, $modefile;
+ system("cat $modefile | $groggy $addopts");
+ &clean_up();
+ next SWITCH;
+ }; # /groff/
+
+ /^(text|tty)$/ and do {
+ my $device;
+ if (! $Opt{'DEVICE'}) {
+ $device = $Opt{'TEXT_DEVICE'};
+ $device = $Default_tty_Device unless $device;
+ } elsif ($Opt{'DEVICE'} =~ /^(ascii||cp1047|latin1|utf8)$/) {
+ $device = $Opt{'DEVICE'};
+ } else {
+ warn "main_display(): wrong device for $Display{'MODE'} mode: " .
+ "$Opt{'DEVICE'}";
+ }
+ $groggy = `cat $tmp_cat | grog -T$device`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ if ($Display{'MODE'} eq 'text') {
+ &_do_opt_V();
+ system("cat $tmp_cat | $groggy $addopts");
+ &clean_up();
+ next SWITCH;
+ }
+
+### main_display()
+ # mode is not 'text', but `tty'
+ my %pager;
+ my @p;
+ push @p, $Opt{'PAGER'} if $Opt{'PAGER'};
+ push @p, $ENV{'PAGER'} if $ENV{'PAGER'};
+ foreach (@p) {
+ %pager = &where_is_prog($_);
+ next unless %pager;
+ if ($pager{'file'} eq 'less') {
+ if ($pager{'args'}) {
+ $pager{'args'} = "-r -R $pager{'args'}";
+ } else {
+ $pager{'args'} = '-r -R';
+ }
+ }
+ last if $pager{'file'};
+ } # foreach @p
+ unless (%pager) {
+ foreach (@{$Viewer_tty{'TTY'}}, @{$Viewer_X{'TTY'}}, 'cat') {
+ next unless $_;
+ %pager = &where_is_prog($_);
+ last if %pager;
+ }
+ }
+ die "main_display(): no pager program found for tty mode;"
+ unless %pager;
+ &_do_opt_V();
+ system("cat $tmp_cat | $groggy $addopts | " .
+ "$pager{'fullname'} $pager{'args'}");
+ &clean_up();
+ next SWITCH;
+ }; # /text|tty/
+
+ /^source$/ and do {
+ open $fh_cat, "<$tmp_cat";
+ foreach (<$fh_cat>) {
+ print "$_";
+ }
+ &clean_up();
+ next SWITCH;
+ };
+
+### main_display()
+ /^dvi$/ and do {
+ if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'dvi') {
+ warn "main_display(): " .
+ "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
+ }
+ $modefile .= '.dvi';
+ $groggy = `cat $tmp_cat | grog -Tdvi`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ &_do_display();
+ next SWITCH;
+ };
+
+ /^html$/ and do {
+ if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'html') {
+ warn "main_display(): " .
+ "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
+ }
+ $modefile .= '.html';
+ $groggy = `cat $tmp_cat | grog -Thtml`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ &_do_display();
+ next SWITCH;
+ };
+
+ /^pdf$/ and do {
+ if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'ps') {
+ warn "main_display(): " .
+ "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
+ }
+ $modefile .= '.ps';
+ $groggy = `cat $tmp_cat | grog -Tps`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ &_do_display(\&_make_pdf);
+ next SWITCH;
+ };
+
+### main_display()
+ /^ps$/ and do {
+ if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'ps') {
+ warn "main_display(): " .
+ "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
+ }
+ $modefile .= '.ps';
+ $groggy = `cat $tmp_cat | grog -Tps`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ &_do_display();
+ next SWITCH;
+ };
+
+ /^x$/ and do {
+ my $device;
+ if ($Opt{'DEVICE'} && $Opt{'DEVICE'} =~ /^X/) {
+ $device = $Opt{'DEVICE'};
+ } else {
+ if ($Opt{'RESOLUTION'} == 100) {
+ if ( $Display{'PROG'} =~ /^(g|)xditview$/ ) {
+ # add width of 800dpi for resolution of 100dpi to the args
+ $Display{'ARGS'} .= ' -geometry 800';
+ $Display{'ARGS'} =~ s/^ //;
+ }
+ } else { # RESOLUTIOM != 100
+ $device = 'X75-12';
+ } # if RESOLUTIOM
+ } # if DEVICE
+ $groggy = `cat $tmp_cat | grog -T$device -Z`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ &_do_display();
+ next SWITCH;
+ };
+
+### main_display()
+ /^X$/ and do {
+ if (! $Opt{'DEVICE'}) {
+ $groggy = `cat $tmp_cat | grog -X`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ } elsif ($Opt{'DEVICE'} =~ /^(X.*|dvi|html|lbp|lj4|ps)$/) {
+ # these devices work with
+ $groggy = `cat $tmp_cat | grog -T$Opt{'DEVICE'} -X`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ } else {
+ warn "main_display(): wrong device for " .
+ "$Display{'MODE'} mode: $Opt{'DEVICE'};";
+ $groggy = `cat $tmp_cat | grog -Z`;
+ die "main_display(): grog error;" if $?;
+ chomp $groggy;
+ print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
+ } # if DEVICE
+ &_do_display();
+ next SWITCH;
+ };
+
+ /^.*$/ and do {
+ die "main_display(): unknown mode `$Display{'MODE'}';";
+ };
+
+ } # SWITCH
+ 1;
+} # main_display()
+
+
+########################
+# _do_display ([<prog>])
+#
+# Perform the generation of the output and view the result. If an
+# argument is given interpret it as a function name that is called in
+# the midst (actually only for `pdf').
+#
+sub _do_display {
+ &_do_opt_V();
+ unless ($Display{'PROG'}) {
+ system("$groggy $addopts $tmp_cat");
+ &clean_up();
+ return 1;
+ }
+ unlink $modefile;
+ die "_do_display(): empty output;" if -z $tmp_cat;
+ system("cat $tmp_cat | $groggy $addopts >$modefile");
+ die "_do_display(): empty output;" if -z $modefile;
+ &print_times("before display");
+ if ($_[0] && ref($_[0]) eq 'CODE') {
+ $_[0]->();
+ }
+ unlink $tmp_cat unless $Debug{'KEEP'};
+
+ if ( $Opt{'STDOUT'} ) {
+ my $fh;
+ open $fh, "<$modefile";
+ foreach (<$fh>) {
+ print;
+ }
+ close $fh;
+ return 1;
+ }
+
+ if ($Viewer_Background) {
+ if ($Debug{'KEEP'}) {
+ exec "$Display{'PROG'} $Display{'ARGS'} $modefile &";
+ } else {
+ exec "{ $Display{'PROG'} $Display{'ARGS'} $modefile; " .
+ "rm -rf $tmpdir; } &";
+ }
+ } else {
+ system("$Display{'PROG'} $Display{'ARGS'} $modefile");
+ &clean_up();
+ }
+} # _do_display() of main_display()
+
+
+#############
+# _do_opt_V ()
+#
+# Check on option `-V'; if set print the corresponding output and leave.
+#
+# Globals: @ARGV, $Display{MODE}, $Display{PROG},
+# $Display{ARGS}, $groggy, $modefile, $addopts
+#
+sub _do_opt_V {
+ if ($Opt{'V'}) {
+ $Opt{'V'} = 0;
+ print "Parameters: @ARGV\n";
+ print "Display Mode: $Display{'MODE'}\n";
+ print "Output file: $modefile\n";
+ print "Display prog: $Display{'PROG'} $Display{'ARGS'}\n";
+ print "Output of grog: $groggy $addopts\n";
+ my $res = `$groggy $addopts\n`;
+ chomp $res;
+ print "groff -V: $res\n";
+ exit 0;
+ }
+ 1;
+} # _do_opt_V() of main_display()
+
+##############
+# _make_pdf ()
+#
+# Transform to pdf format; for pdf mode in _do_display().
+#
+# Globals: $md_modefile (from main_display())
+#
+sub _make_pdf {
+ die "_make_pdf(): pdf mode did not work;" if $PDF_Did_Not_Work;
+ my $psfile = $modefile;
+ die "_make_pdf(): empty output;" if -z $modefile;
+ $modefile =~ s/\.ps$/.pdf/;
+ unlink $modefile;
+ my $done;
+ if ($PDF_Has_ps2pdf) {
+ system("ps2pdf $psfile $modefile 2>$Dev_Null");
+ $done = ! $?;
+ }
+ if (! $done && $PDF_Has_gs) {
+ system("gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite " .
+ "-sOutputFile=$modefile -c save pop -f $psfile 2>$Dev_Null");
+ $done = ! $?;
+ }
+ if (! $done) {
+ $PDF_Did_Not_Work = 1;
+ warn '_make_pdf(): Could not transform into pdf format, ' .
+ 'the Postscript mode (ps) is used instead;';
+ $Opt{'MODE'} = 'ps';
+ &main_set_mode();
+ &main_set_resources();
+ &main_display();
+ exit 0;
+ }
+ unlink $psfile unless $Debug{'KEEP'};
+ 1;
+} # _make_pdf() of main_display()
+
+
+########################################################################
+
+&main_set_options();
+&main_parse_MANOPT();
+&main_config_params();
+&main_parse_params();
+&main_set_mode();
+&main_temp();
+&main_do_fileargs();
+&main_set_resources();
+&main_display();
+
+&clean_up();
+
+1;
+########################################################################
+### Emacs settings
+# Local Variables:
+# mode: CPerl
+# End:
diff --git a/contrib/groffer/perl/man.pl b/contrib/groffer/perl/man.pl
new file mode 100644
index 00000000..91c65cd2
--- /dev/null
+++ b/contrib/groffer/perl/man.pl
@@ -0,0 +1,731 @@
+#! /usr/bin/env perl
+
+# groffer - display groff files
+
+# Source file position: <groff-source>/contrib/groffer/perl/man.pl
+# Installed position: <prefix>/lib/groff/groffer/man.pl
+
+# Copyright (C) 2006, 2009, 2011 Free Software Foundation, Inc.
+# Written by Bernd Warken <groff-bernd.warken-72@web.de>.
+
+# Last update: 27 Jan 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/>.
+
+########################################################################
+
+use strict;
+use warnings;
+
+########################################################################
+# functions for apropos, man, whatis
+########################################################################
+
+##########
+# apropos_filespec()
+#
+# Compose temporary file for filspec.
+#
+# Globals: in: $main::Opt{'APROPOS'}, $main::Special_Setup, $main::Filespec_Arg,
+# $main::Apropos_Prog, $main::Opt{'APROPOS_SECTIONS'}, $main::Opt{'SECTIONS'}
+# out: $main::Special_Filespec
+#
+sub apropos_filespec {
+ return 0 unless $main::Opt{'APROPOS'};
+ die 'apropos_filespec(): apropos_setup() must be run first;'
+ unless $main::Special_Setup;
+ die 'apropos_filespec(): no $main::Filespec_Arg is set;'
+ unless defined $main::Filespec_Arg;
+ $main::Special_Filespec = 1;
+
+ my $s;
+ if ($main::No_Filespecs) {
+ &to_tmp_line('.SH no filespec');
+ $s = `$main::Apropos_Prog`;
+ $s =~ s/^/\\\&/;
+ &to_tmp_line($s);
+ return 1;
+ }
+
+ $s = $main::Filespec_Arg;
+ $s =~ s/[^\\]-/\\-/g;
+ &to_tmp_line(".SH $s");
+
+ if ( $main::Opt{'APROPOS_SECTIONS'} ) {
+ $s = qr/^[^\(]*\([$main::Opt{'APROPOS_SECTIONS'}]/;
+ } else {
+ if ( $main::Opt{'SECTIONS'} ) {
+ $s = $main::Opt{'SECTIONS'};
+ $s = qr/^[^\(]*\([$s]/;
+ } else {
+ $s = qr/^.*\(.+\).*$/;
+ }
+ }
+
+### apropos_filespec()
+ my $filespec = $main::Filespec_Arg;
+ $filespec =~ s#/#\\/#g;
+ $filespec =~ s#\.#\\./#g;
+ my @ap;
+ foreach ( `$main::Apropos_Prog $main::Filespec_Arg 2>$main::Dev_Null` ) {
+ chomp;
+ if (/^$filespec:\s/) { # for error messages of this script
+ my $line = $_;
+ $line =~ s/^(.*)$/\\\&$1/s;
+ push @ap, $line;
+ }
+ if (/$s/) {
+ push @ap, $_;
+ }
+ }
+ my @res;
+ foreach (sort @ap) {
+ s/^
+ ([^\(]+\(+[$main::Man{'AUTO_SEC_CHARS'}][^\)]*\)+)
+ (\s*-*)*\s*
+ (.*)
+ $/.br\n.TP 15\n.BR "$1"\n\\\&$3\n/sx;
+ push @res, $_;
+ }
+ &to_tmp_line(@res);
+ 1;
+} # apropos_filespec()
+
+
+##########
+# apropos_setup()
+#
+# Setup for the --apropos* options, just 2 global variables are set.
+#
+# Globals: in: $main::Opt{'APROPOS'}
+# out: $main::Special_Setup, $main::Apropos_Prog
+#
+sub apropos_setup {
+ return 0 unless $main::Opt{'APROPOS'};
+ if ( &where_is_prog('apropos') ) {
+ $main::Apropos_Prog = 'apropos';
+ } elsif ( &where_is_prog('man') ) {
+ if (! system("man --apropos man >$main::Dev_Null 2>$main::Dev_Null")) {
+ $main::Apropos_Prog = 'man --apropos';
+ } elsif (! system("man -k man >$main::Dev_Null 2>$main::Dev_Null")) {
+ $main::Apropos_Prog = 'man --k';
+ }
+ } # test man
+ die 'apropos_setup(): no apropos program available;'
+ unless $main::Apropos_Prog;
+ &to_tmp_line('.TH GROFFER APROPOS');
+ $main::Special_Setup = 1;
+ $main::Opt{'TITLE'} = 'apropos' unless $main::Opt{'TITLE'};
+ 1;
+} # apropos_setup()
+
+
+##########
+# is_man(<man_sec_ext-hash-ref>)
+#
+# Test whether the argument hash exists as man page (from is_man()).
+#
+# Globals: in: $main::Man{AUTO_SEC_CHARS},$main::Man{SEC_CHARS},
+# $main::Man{EXT}, $tmpdir
+# out: $main::Manspec
+#
+# Arguments: 1, a hash reference with keys 'name', 'sec', 'ext', where
+# 'sec' is a string of one or several section characters
+#
+sub is_man {
+ my $n = @_;
+ die "is_man(): one argument is needed, you used $n;"
+ unless $n == 1;
+ die "is_man(): the argument is not a hash reference `$_[0]';"
+ if ref($_[0]) ne 'HASH';
+ die 'is_man(): temporary directory is not set;' unless $main::tmpdir;
+ die 'is_man(): man_setup() must be run first;' unless $main::Man{'IS_SETUP'};
+
+ my $name = $_[0]->{'name'};
+ unless ($name) {
+ $main::Manspec = '';
+ return 0;
+ }
+
+ my $sec;
+ $sec = $_[0]->{'sec'};
+ $sec = $main::Man{'SEC_CHARS'} unless $sec;
+ $sec = $main::Man{'AUTO_SEC_CHARS'} unless $sec;
+ $sec = '' unless defined $sec;
+ # take care, $sec may be several sections
+
+### is_man()
+ my $ext;
+ $ext = $_[0]->{'ext'};
+ $ext = $main::Man{'EXT'} unless $ext;
+ $ext = '' unless defined $ext;
+
+ $main::Manspec = "$name.$sec,$ext";
+ my @m;
+ if (exists $main::Man{'MANSPEC'}{$main::Manspec}) {
+ return 1;
+ } else {
+ foreach my $p ( @{$main::Man{'PATH'}} ) {
+ foreach my $s (split //, $sec) {
+ my $dir = File::Spec->catdir($p, "man$s");
+ next unless -d $dir;
+ my $file = File::Spec->catfile($dir, "$name.$s$ext");
+ push @m, glob("$file*");
+ }
+ }
+ $main::Man{'MANSPEC'}{$main::Manspec} = \@m;
+ }
+ return 0 unless (@m);
+ return 1;
+} # is_man()
+
+
+##########
+# man_get (<man_sec_ext-hash-ref>)
+#
+# Write a man page to the temporary file.
+#
+# Globals in: $main::Manspec, $main::Man{MANSPEC}, $main::Man{SEC_CHARS},
+# $main::Man{EXT}, $main::Man{ALL}
+#
+# Arguments: 1, a hash reference with keys 'name', 'sec', 'ext', where
+# 'sec' is a string of one or several section characters
+#
+sub man_get {
+ my $n = @_;
+ die "man_get(): one argument is needed, you used $n;"
+ unless $n == 1;
+ die "man_get(): the argument is not a hash reference `$_[0]';"
+ if ref($_[0]) ne 'HASH';
+ die "man_get(): is_man() must be run first on the argument;"
+ unless $main::Manspec;
+ die "man_get(): wrong hash reference `$_[0]', no 'name' key;"
+ unless exists $_[0]->{'name'};
+
+ my ($name, $sec, $ext, $f, $path);
+ $name = $_[0]->{'name'};
+ die "man_get(): empty 'name' key in the argument;" unless $name;
+
+ $sec = $_[0]->{'sec'};
+ $sec = $main::Man{'SEC_CHARS'} if (! $sec) and $main::Man{'SEC_CHARS'};
+ $sec = '' unless defined $sec;
+ # take care $sec may be several sections
+
+### man_get()
+ $ext = $_[0]->{'ext'};
+ $ext = $main::Man{'EXT'} unless $ext;
+ $ext = '' unless defined $ext;
+
+ die 'man_get(): $main::Manspec does not suit the arguments;'
+ if ($main::Manspec ne "$name.$sec,$ext") and
+ (! exists $main::Man{'MANSPEC'}{$main::Manspec});
+
+ if ($main::Man{'ALL'}) {
+ my $ok;
+ my %list;
+ foreach ( @{$main::Man{'MANSPEC'}{$main::Manspec}} ) {
+ next if exists $list{$_};
+ if (-f $_ and -r $_) {
+ $list{$_} = 1;
+ &to_tmp($_);
+ $ok = 1;
+ }
+ }
+ &register_title("man:$name") if $ok;
+ return 1;
+ }
+
+ # not $main::Man{'ALL'}
+
+ if ($_[0]->{'sec'}) {
+ my $path = File::Spec->catfile('', "man$sec", $name);
+ if ($ext) {
+ foreach $f ( @{$main::Man{'MANSPEC'}{$main::Manspec}} ) {
+ if ($f =~ m#$path\.$sec$ext($|\..*$)#) {
+ if (-f $f && -r $f) {
+ &register_file($f);
+ return 1;
+ }
+ } # if $f =~
+ } # foreach $f
+### man_get()
+ foreach $f ( @{$main::Man{'MANSPEC'}{$main::Manspec}} ) {
+ if ($f =~ m#$path\.$sec$ext.*$#) {
+ if (-f $f && -r $f) {
+ &register_file($f);
+ return 1;
+ }
+ } # if $f =~
+ } # foreach $f
+ } else { # $ext is empty
+ foreach $f ( @{$main::Man{'MANSPEC'}{$main::Manspec}} ) {
+ if ($f =~ m#$path\.$sec($|\..*$)#) {
+ if (-f $f && -r $f) {
+ # &to_tmp($f) && &register_file($f);
+ &register_file($f);
+ return 1;
+ }
+ } # if $f =~
+ } # foreach $f
+ foreach $f ( @{$main::Man{'MANSPEC'}{$main::Manspec}} ) {
+ if ($f =~ m#$path\.$sec.*$#) {
+ if (-f $f && -r $f) {
+ # &to_tmp($f) && &register_file($f);
+ &register_file($f);
+ return 1;
+ }
+ } # if $f =~
+ } # foreach $f
+ } # if $ext
+### man_get()
+ } else { # sec is empty
+ my $m = $main::Man{'SEC_CHARS'};
+ $m = $main::Man{'AUTO_SEC_CHARS'} unless $m;
+ foreach my $s (split //, $m) {
+ my $path = File::Spec->catfile('', "man$s", $name);
+ unless ($ext) {
+ foreach my $f ( @{$main::Man{'MANSPEC'}{$main::Manspec}} ) {
+ if ( $f =~ m#$path\.$s($|\..*$)# ) {
+ if (-f $f && -r $f) {
+ # &to_tmp($f) && &register_file($f);
+ &register_file($f);
+ return 1;
+ }
+ } # if $f =~
+ } # foreach $f
+ } # unless $ext
+ foreach $f ( @{$main::Man{'MANSPEC'}{$main::Manspec}} ) {
+ if ($f =~ m#$path\.$s$ext.*$#) {
+ if (-f $f && -r $f) {
+ # &to_tmp($f) && &register_file($f);
+ &register_file($f);
+ return 1;
+ }
+ } # if $f =~
+ } # foreach $f
+ } # foreach $s
+ } # if sec
+
+ 1;
+} # man_get()
+
+
+##########
+# man_setup ()
+#
+# Setup the variables in %MAN needed for man page searching.
+#
+# Globals:
+# in: %OPT, $LANG, $LC_MESSAGES, $LC_ALL,
+# $MANPATH, $MANSEC, $PAGER, $SYSTEM, $MANOPT.
+# out: $main::Man{PATH}, $main::Man{LANG}, $main::Man{LANG2}, $main::Man{SYS},
+# $main::Man{SEC}, $main::Man{ALL}
+# in/out: $main::Man{ENABLE}
+#
+# The precedence for the variables related to `man' is that of GNU
+# `man', i.e.
+#
+# $LANG; overridden by
+# $LC_MESSAGES; overridden by
+# $LC_ALL; this has the same precedence as
+# $MANPATH, $MANSEC, $PAGER, $SYSTEM; overridden by
+# $MANOPT; overridden by
+# the groffer command line options.
+#
+# $MANROFFSEQ is ignored because grog determines the preprocessors.
+#
+sub man_setup {
+ return 1 if $main::Man{'IS_SETUP'};
+ $main::Man{'IS_SETUP'} = 1;
+ return 1 unless $main::Man{'ENABLE'};
+
+ # determine basic path for man pages
+ my $path;
+ if (defined $main::Opt{'MANPATH'}) {
+ $path = $main::Opt{'MANPATH'};
+ } elsif ($ENV{'MANPATH'}) {
+ $path = $ENV{'MANPATH'};
+ } elsif ( &where_is_prog('manpath') ) {
+ $path = `manpath 2>$main::Dev_Null`;
+ }
+ if ($path) {
+ chomp $path;
+ $main::Man{'PATH'} = [split /:/, $path];
+ } else {
+ $main::Man{'PATH'} = [];
+ &manpath_set_from_path();
+ }
+ unless ( @{$main::Man{'PATH'}} ) {
+ $main::Man{'ENABLE'} = 0;
+ warn "man_setup(): man path is empty;";
+ return 1;
+ }
+
+### man_setup()
+ # make man path list consisting of unique existing directories
+ @{$main::Man{'PATH'}} = &path_uniq( @{$main::Man{'PATH'}} );
+
+ unless ($main::Man{'ALL'}) {
+ $main::Man{'ALL'} = $main::Opt{'ALL'} ? 1 : 0;
+ }
+
+ # handle man systems
+ my $sys = $ENV{'SYSTEM'};
+ $sys = $main::Opt{'SYSTEMS'} if $main::Opt{'SYSTEMS'};
+ if ($sys) {
+ chomp $sys;
+ $main::Man{'SYS'} = [split /,/, $sys];
+ } else {
+ $main::Man{'SYS'} = [];
+ $sys = '';
+ }
+
+### man_setup()
+ # handle language
+ my $lang = '';
+ $lang = $main::Opt{'LANG'} if $main::Opt{'LANG'};
+ unless ($lang) {
+ foreach ('LC_ALL', 'LC_MESSAGES', 'LANG') {
+ if ($ENV{$_}) {
+ $lang = $ENV{$_};
+ last;
+ }
+ }
+ }
+ if ($lang) {
+ if ($lang eq 'C' or $lang eq 'POSIX') {
+ $main::Man{'LANG'} = '';
+ $main::Man{'LANG2'} = '';
+ } elsif ($lang =~ /^.$/) {
+ $main::Man{'LANG'} = $lang;
+ $main::Man{'LANG2'} = '';
+ } elsif ($lang =~ /^..$/) {
+ $main::Man{'LANG'} = $lang;
+ $main::Man{'LANG2'} = $lang;
+ } else {
+ $main::Man{'LANG'} = $lang;
+ $main::Man{'LANG2'} = $lang;
+ $main::Man{'LANG2'} =~ s/^(..).*$/$1/;
+ }
+ } # if ($lang)
+ # from now on, use only $main::Man{LANG*}, forget about $main::Opt{LANG}, $ENV{LC_*}.
+
+ &manpath_add_lang_sys();
+
+### man_setup()
+ # section
+ my $sec;
+ $sec = $main::Opt{'SECTIONS'} if $main::Opt{'SECTIONS'};
+ unless ($sec) {
+ $sec = $ENV{'MANSEC'} if $ENV{'MANSEC'};
+ }
+ $main::Man{'SEC'} = [];
+ $main::Man{'SEC_CHARS'} = '';
+ if ($sec) {
+ foreach (split /:/, $sec) {
+ push @{$main::Man{'SEC'}}, $_ if /^[$main::Man{'AUTO_SEC_CHARS'}]$/;
+ }
+ $main::Man{'SEC_CHARS'} = join '', @{$main::Man{'SEC'}} if @{$main::Man{'SEC'}};
+ } # if ($sec)
+
+ # extension
+ my $ext = '';
+ $ext = $main::Opt{'EXTENSION'} if $main::Opt{'EXTENSION'};
+ unless ($ext) {
+ $ext = $ENV{'EXTENSION'} if $ENV{'EXTENSION'};
+ }
+ $main::Man{'EXT'} = $ext;
+
+ # creation of man temporary is omitted, because of globs in perl
+ 1;
+} # man_setup()
+
+
+##########
+# manpath_add_lang_sys()
+#
+# Add language and operating system specific directories to man path.
+#
+# Globals:
+# in: $main::Man{SYS}: a list of names of operating systems.
+# $main::Man{LANG} and $main::Man{LANG2}: each a single name
+# in/out: @{$main::Man{PATH}}: list of directories which shall have the `man?'
+# subdirectories.
+#
+sub manpath_add_lang_sys {
+ return 1 unless $main::Man{'PATH'};
+ return 1 unless @{$main::Man{'PATH'}};
+
+ my @mp;
+
+ if ( @{$main::Man{'SYS'}} ) {
+ foreach ( @{$main::Man{'SYS'}} ) {
+ if ($_ eq 'man') {
+ @mp = (@mp, @{$main::Man{'PATH'}});
+ } elsif ($_) {
+ my $sys = $_;
+ foreach my $p (@{$main::Man{'PATH'}}) {
+ my $dir = File::Spec->catdir($p, $sys);
+ push @mp, $dir;
+ }
+ } # if eq 'man'
+ } # foreach SYS
+ } else { # no SYS
+ @mp = @{$main::Man{'PATH'}};
+ }
+
+ if (@mp && $main::Man{'LANG'}) {
+ my @lang_path;
+ my $man_lang2 = '';
+ $man_lang2 = $main::Man{'LANG2'} if $main::Man{'LANG'} ne $main::Man{'LANG2'};
+ foreach my $i ($main::Man{'LANG'}, $man_lang2) {
+ next unless $i;
+ my $lang = $i;
+ foreach my $p (@mp) {
+ my $dir = File::Spec->catdir($p, $lang);
+ push @lang_path, $dir;
+ } # foreach $p
+ } # foreach $i
+ @mp = (@lang_path, @mp);
+ } # if $mp
+
+ $main::Man{PATH} = [&path_uniq(@mp)];
+ 1;
+} # manpath_add_lang_sys()
+
+
+##########
+# manpath_set_from_path()
+#
+# Determine basic search path for man pages from $PATH.
+#
+# Return: `1' if a valid man path was retrieved.
+# Output: none
+# Globals:
+# in: $PATH
+# out: $_MAN_PATH
+#
+sub manpath_set_from_path {
+ my @path =
+ qw( /usr/local /usr /usr/X11R6 /usr/openwin /opt /opt/gnome /opt/kde );
+ # get a basic man path from $ENV{PATH}
+ my @path2 = @main::Path;
+ foreach (@path2) {
+ s#bin/*$##;
+ push @path, $_;
+ }
+ @path = &path_uniq(@path);
+ foreach my $d (@path) {
+ foreach my $e ( File::Spec->catdir( qw(share man) ),
+ File::Spec->catdir( qw(share MAN) ),
+ 'man', 'MAN' ) {
+ my $dir = File::Spec->catdir($d, $e);
+ push @{$main::Man{'PATH'}}, $dir if -d $dir;
+ }
+ }
+ 1;
+} # manpath_set_from_path()
+
+
+##########
+# special_filespec()
+#
+# Handle special modes like whatis and apropos. Run their filespec
+# functions if suitable.
+#
+# Globals: in: $main::Opt{'APROPOS'}, $main::Opt{'WHATIS'}, $main::Special_Setup
+# out: $main::Special_Filespec (internal)
+#
+sub special_filespec {
+ return 0 unless $main::Opt{'APROPOS'} || $main::Opt{'WHATIS'};
+ die 'special_filespec(): setup for apropos or whatis must be run first;'
+ unless $main::Special_Setup;
+ if ( $main::Opt{'APROPOS'} ) {
+ die "special_setup(): both apropos and whatis option variables are set;"
+ if $main::Opt{'WHATIS'};
+ return &apropos_filespec() ? 1 : 0;
+ }
+ if ( $main::Opt{'WHATIS'} ) {
+ return &whatis_filespec() ? 1 : 0;
+ }
+ 0;
+} # special_filespec
+
+
+##########
+# special_setup()
+#
+# Handle special modes like whatis and apropos. Run their setup
+# functions if suitable.
+#
+sub special_setup {
+ if ( $main::Opt{'APROPOS'} ) {
+ die "special_setup(): both --apropos and --whatis option variables " .
+ "are set;" if $main::Opt{'WHATIS'};
+ return &apropos_setup() ? 1 : 0;
+ }
+ if ( $main::Opt{'WHATIS'} ) {
+ return &whatis_setup() ? 1 : 0;
+ }
+ 0;
+} # special_setup()
+
+
+##########
+# whatis_filename(<filename>)
+#
+# Interpret <filename> as a man page and display its `whatis'
+# information as a fragment written in the groff language.
+#
+# Globals: in: $main::Opt{'WHATIS'}, $main::Special_Setup, $main::Special_Filespec,
+# $main::Filespec_Arg
+#
+sub whatis_filename {
+ my $n = @_;
+ die "whatis_filename(): one argument is needed; you used $n;"
+ unless $n == 1;
+ die "whatis_filename(): whatis is not setup;" unless $main::Opt{'WHATIS'};
+ die "whatis_filename(): setup for whatis must be run first;"
+ unless $main::Special_Setup;
+ die "whatis_filename(): whatis_filespec() must be run first;"
+ unless $main::Special_Filespec;
+ die 'whatis_filename(): no $main::Filespec_Arg is set;'
+ unless defined $main::Filespec_Arg;
+
+ my $arg = $_[0];
+ die "whatis_file_name(): $arg is not an existing file" unless -f $arg;
+ die "whatis_file_name(): could not read file $arg" unless -r $arg;
+ return 1 if -z $arg;
+ $arg = 'stdin' if $main::Filespec_Arg eq '-';
+
+ &to_tmp_line('.br', '\\f[CR]' . $arg . '\\f[]:', '.br');
+
+### whatis_filename()
+ # get the parts of the file name according to the naming of man pages
+ my ($dir, $name) = &split_path( $_[0] );
+ my $section = $_[0];
+ my $path = File::Spec->catfile('', 'man');
+ $section =~ s#^.*$path([$main::Man{'AUTO_SEC_CHARS'}]).*$#$1#;
+ $section = '' if $section eq $_[0];
+ if ($section) {
+ if ($name =~ m#^.*\.$section.*$#) {
+ $name =~ s/^(.*)\.$section.*$/$1/;
+ } else {
+ $section = '';
+ }
+ }
+
+ # traditional man style; grep the line containing `.TH' macro, if any
+ my @catz = &cat_z($_[0]);
+ my $res;
+ my $test;
+ foreach (@catz) {
+ if (/^[\.']\s*TH\s/) { # search .TH, traditional man style
+ $test = 1;
+ last;
+ }
+ } # foreach (@catz)
+### whatis_filename()
+ if ($test) { # traditional man style
+ # get the first line after the first `.SH' macro before the next `.SH'
+ my $test1;
+ foreach (@catz) {
+ if ($test1) {
+ chomp;
+ next unless $_;
+ next if /^[\.']?\s*$/;
+ last if /^[\.']/; # especially for .SH
+ if ($res) {
+ $res = "$res $_";
+ } else {
+ $res = $_;
+ }
+ } else { # $test1 is empty
+ $test1 = 1 if (/^[\.']\s*SH\s/);
+ } # if ($test1)
+ } # foreach (@catz)
+
+ if ($section) {
+ if ($res =~ m|^
+ $name
+ \s
+ [^-]*
+ -
+ \s*
+ (.*)
+ $|sx) {
+ $res = "$name ($section) \\[em] $1";
+ }
+ } # if ($section)
+### whatis_filename()
+ &to_tmp_line($res, '.br', '', '.br');
+ return 1;
+ } # if ($test)
+
+ # mdoc style (BSD doc); grep the line containing `.Nd' macro, if any
+ foreach (@catz) {
+ if (/^[\.']\s*Nd\s/) { # BSD doc style
+ $res =~ s/^(.*)$/$name ($section) \\[em] $1/;
+ &to_tmp_line($res);
+ return 1;
+ }
+ }
+
+ &to_tmp_line('is not a man page', '.br', '', '.br');
+ 1;
+} # whatis_filename()
+
+
+##########
+# whatis_filespec()
+#
+# Print the filespec name as .SH to the temporary cat file.
+#
+# Globals: in: $main::Opt{'WHATIS'}, $main::Filespec_Arg
+# in/out: $main::Special_Filespec
+#
+sub whatis_filespec {
+ return 0 unless ($main::Opt{'WHATIS'});
+ die 'whatis_filespec(): whatis_setup() must be run first.'
+ unless $main::Special_Setup;
+ die 'whatis_filespec(): no $main::Filespec_Arg is set;'
+ unless defined $main::Filespec_Arg;
+ $main::Special_Filespec = 1;
+ my $arg = $main::Filespec_Arg;
+ $arg =~ s/[^\\]-/\\-/g;
+ to_tmp_line(".SH $arg");
+} # whatis_filespec()
+
+
+##########
+# whatis_setup ()
+#
+# Print the whatis header to the temporary cat file; this is the setup
+# for whatis.
+#
+# Globals: in: $main::Opt{'WHATIS'}
+# out: $main::Special_Setup
+sub whatis_setup {
+ if ( $main::Opt{'WHATIS'} ) {
+ &to_tmp_line('.TH GROFFER WHATIS');
+ $main::Special_Setup = 1;
+ $main::Opt{'TITLE'} = 'whatis' unless $main::Opt{'TITLE'};
+ return 1;
+ }
+ 0;
+} # whatis_setup ()
+
+1;
diff --git a/contrib/groffer/perl/perl_test.pl b/contrib/groffer/perl/perl_test.pl
new file mode 100644
index 00000000..e92fc3c8
--- /dev/null
+++ b/contrib/groffer/perl/perl_test.pl
@@ -0,0 +1,34 @@
+#! /usr/bin/env perl
+
+# groffer - display groff files
+
+# Source file position: <groff-source>/contrib/groffer/perl/perl_test.sh
+# Installed position: <prefix>/lib/groff/groffer/perl_test.sh
+
+# 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 `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/>.
+
+########################################################################
+
+# This file tests whether perl has a suitable version. It is used by
+# groffer.pl and Makefile.sub.
+
+# require 5.004_05;
+require v5.6.1;
diff --git a/contrib/groffer/perl/roff2.pl b/contrib/groffer/perl/roff2.pl
new file mode 100755
index 00000000..c3e6047f
--- /dev/null
+++ b/contrib/groffer/perl/roff2.pl
@@ -0,0 +1,223 @@
+#! /usr/bin/env perl
+
+# roff2* - transform roff files into other formats
+
+# Source file position: <groff-source>/contrib/groffer/perl/roff2.pl
+# Installed position: <prefix>/bin/roff2*
+
+# Copyright (C) 2006, 2008, 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 `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/>.
+
+########################################################################
+
+require v5.6;
+
+use strict;
+use warnings;
+use File::Spec;
+
+# temporary dir and files
+use File::Temp qw/ tempfile /;
+
+my $Dev_Null = File::Spec->devnull();
+my $Mode;
+my $Name;
+{
+ my ($v, $d);
+ ($v, $d, $Name) = File::Spec->splitpath($0);
+ die "wrong program name: $Name;"
+ if $Name !~ /^roff2[a-z]/;
+}
+$Mode = $Name;
+$Mode =~ s/^roff2//;
+
+my $Groff_Version = `groff --version 2>$Dev_Null`;
+die "$Name error: groff does not work;" if $?;
+my $Groffer_Version = `groffer --version 2>$Dev_Null`;
+my $Has_Groffer = ! $?;
+
+if ($Has_Groffer) {
+ foreach (@ARGV) {
+ last if $_ eq '--';
+ next if $_ eq '-';
+ if ($_ eq '-v' || '--version' =~ m|^$_|) {
+ print $Name, ' in ', $Groffer_Version;
+ exit 0;
+ }
+ if ($_ eq '-h' || '--help' =~ m|^$_|) {
+ &usage_with_groffer();
+ exit 0;
+ }
+ }
+ system('groffer', '--to-stdout', "--$Mode", @ARGV);
+ exit $?;
+} else {
+ my @filespec;
+ my $double_minus;
+ foreach (@ARGV) {
+ if ($double_minus) {
+ push @filespec, $_;
+ next;
+ }
+ if ($_ eq '--') {
+ $double_minus = 1;
+ next;
+ }
+ if ($_ eq '-') {
+ push @filespec, '-';
+ next;
+ }
+ if ($_ eq '-v' || '--version' =~ m|^$_|) {
+ print $Name, ' in ', $Groff_Version;
+ exit 0;
+ }
+ if ($_ eq '-h' || '--help' =~ m|^$_|) {
+ &usage_without_groffer();
+ exit 0;
+ }
+ if ($_ =~ /^-/) {
+ &error_no_groffer();
+ &error_no_options();
+ next;
+ }
+ if (-f && -r) {
+ push @filespec, $_;
+ } else {
+ &error_no_groffer();
+ print STDERR "$_ is not an existing, readable file.\n";
+ }
+ }
+
+ @filespec = ('-') unless @filespec;
+ my $has_stdin;
+ foreach (@filespec) {
+ if ($_ eq '-') {
+ $has_stdin =1;
+ last;
+ }
+ }
+
+ if ($has_stdin) {
+ my $tempdir;
+ foreach ($ENV{'GROFF_TMPDIR'}, $ENV{'TMPDIR'}, $ENV{'TMP'},
+ $ENV{'TEMP'}, $ENV{'TEMPDIR'},
+ File::Spec->catfile($ENV{'HOME'}, 'tmp')) {
+ if ($_ && -d $_ && -w $_) {
+ $tempdir = $_;
+ last;
+ }
+ }
+ my $template = $Name . '_XXXX';
+ my ($fh, $stdin);
+ if ($tempdir) {
+ ($fh, $stdin) = tempfile($template, UNLINK => 1, DIR => $tempdir) ||
+ die "$Name: could not create temporary file;";
+ } else {
+ ($fh, $stdin) = tempfile($template, UNLINK => 1) ||
+ die "$Name: could not create temporary file;";
+ }
+ open $fh, ">$stdin";
+ print $fh $_ foreach <STDIN>;
+
+ foreach (@filespec) {
+ $_ = $stdin if $_ eq '-';
+ }
+ } # if $has_stdin
+
+ my $grog;
+ my $groff_options = "-T$Mode";
+ $groff_options = '-TX75-12 -Z' if $Mode eq 'x';
+ $groff_options = '-Tlatin1' if $Mode eq 'text';
+ if ($Mode eq 'pdf') {
+ my $ps2pdf;
+ my @path = File::Spec->path();
+ foreach (@path) {
+ my $file = File::Spec->catfile($_, 'ps2pdf');
+ if (-f $file && -x $file) {
+ $ps2pdf = "$file -";
+ last;
+ }
+ }
+ unless ($ps2pdf) {
+ foreach (@path) {
+ my $file = File::Spec->catfile($_, 'gs');
+ if (-f $file && -x $file) {
+ $ps2pdf = $file . ' -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite ' .
+ '-sOutputFile=- -c save pop -f -';
+ last;
+ }
+ }
+ }
+ $grog = `grog -Tps @filespec`;
+ chomp $grog;
+ system("$grog | $ps2pdf");
+ exit $?;
+ } else {
+ $grog = `grog $groff_options @filespec`;
+ chomp $grog;
+ system($grog);
+ exit $?;
+ }
+}
+
+my $error_no_groffer;
+sub error_no_groffer {
+ return 1 if $error_no_groffer;
+ $error_no_groffer = 1;
+ print STDERR "$Name: groffer is not available.\n";
+}
+
+my $error_no_options;
+sub error_no_options {
+ return 1 if $error_no_options;
+ $error_no_groffer = 1;
+ print STDERR "$Name: groffer options are not allowed.\n";
+}
+
+sub usage_with_groffer {
+ print <<EOF;
+usage: $Name [option]... [--] [filespec]...
+
+-h | --help print usage information
+-v | --version print version information
+
+All other options are arbitrary options of `groffer'; the options
+override the behavior of this program.
+
+`filespec's are the same as in `groffer': either the names of
+existing, readable files or `-' for standard input or a search pattern
+for man pages. No `filespec' assumes standard input automatically.
+EOF
+}
+
+sub usage_without_groffer {
+ print <<EOF;
+usage: $Name [option]... [--] [filespec]...
+
+-h | --help print usage information
+-v | --version print version information
+
+No other options are allowed because `groffer' is not available.
+
+The only `filespec's allowed are the names of existing, readable files
+or `-' for standard input. No `filespec' assumes standard input
+automatically.
+EOF
+}
diff --git a/contrib/groffer/perl/split_env.sh b/contrib/groffer/perl/split_env.sh
new file mode 100644
index 00000000..f9392610
--- /dev/null
+++ b/contrib/groffer/perl/split_env.sh
@@ -0,0 +1,48 @@
+#! /bin/sh
+
+# groffer - display groff files
+
+# Source file position: <groff-source>/contrib/groffer/perl/split_env.sh
+# Installed position: <prefix>/lib/groff/groffer/split_env.sh
+
+# 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 `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/>.
+
+########################################################################
+
+# This file is called from groffer.pl. The environment variable
+# of the name in $1 will be split at output. The corresponding variable
+# must be exported before the call of groffer.pl.
+
+if test $# = 0
+then
+ echo 'split_env.sh was called without an argument.' >&2;
+else
+ eval v='"$'"$1"'"';
+ if test _"$v"_ != __
+ then
+ eval set x $v;
+ shift;
+ for i in "$@";
+ do
+ echo $i;
+ done;
+ fi;
+fi;